From 5dd444a3dd688b366e1151739f6a8e8088bb0623 Mon Sep 17 00:00:00 2001 From: Visuwesh Date: Sat, 16 Mar 2024 09:10:53 +0530 Subject: [PATCH] ob-calc: Support passing tables as matrices with :var A table with MxN dimensions is converted to a MxN matrix when given in :var to a Calc source block. A table with a single row is converted to a vector (i.e., row vector). * lisp/ob-calc.el (org-babel-execute-src-block:calc): Construct the right data structure to pass tables as matrices to Calc. * testing/examples/ob-calc-test.org: * testing/lisp/test-ob-calc.el: Add tests for ob-calc, and this new feature. --- lisp/ob-calc.el | 10 +++- testing/examples/ob-calc-test.org | 57 ++++++++++++++++++++++ testing/lisp/test-ob-calc.el | 80 +++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 testing/examples/ob-calc-test.org create mode 100644 testing/lisp/test-ob-calc.el diff --git a/lisp/ob-calc.el b/lisp/ob-calc.el index f36df77ff..c8bbcd16b 100644 --- a/lisp/ob-calc.el +++ b/lisp/ob-calc.el @@ -64,7 +64,15 @@ (var-names (mapcar #'symbol-name org--var-syms))) (mapc (lambda (pair) - (calc-push-list (list (cdr pair))) + (let ((val (cdr pair))) + (calc-push-list + (list (if (listp val) + (cons 'vec + (if (null (cdr val)) + (car val) + (mapcar (lambda (x) (if (listp x) (cons 'vec x) x)) + val))) + val)))) (calc-store-into (car pair))) vars) (mapc diff --git a/testing/examples/ob-calc-test.org b/testing/examples/ob-calc-test.org new file mode 100644 index 000000000..6df44c6a4 --- /dev/null +++ b/testing/examples/ob-calc-test.org @@ -0,0 +1,57 @@ +#+TITLE: Tests for ob-calc +#+OPTIONS: ^:nil + +* Simple +:PROPERTIES: +:ID: 40e4cd26-fe15-45c0-938b-111e021a5a99 +:END: + +#+BEGIN_SRC calc :results silent + 1 * 2 +#+END_SRC + +#+BEGIN_SRC calc :results silent + 12 + 16 - 1 +#+END_SRC + +#+BEGIN_SRC calc :results silent + inv(a) +#+END_SRC + +* Tables +:PROPERTIES: +:ID: 138938e1-f0ba-4c2b-babe-5d20f2b83557 +:END: + +#+NAME: ob-calc-table-1 +| 1 | 2 | 3 | +| 5 | 6 | 7 | +| 9 | 14 | 11 | + +#+NAME: ob-calc-table-2 +| 1 | 2 | 3 | 4 | 5 | + +#+NAME: ob-calc-table-3 +| 1 | +| 2 | +| 3 | + +#+BEGIN_SRC calc :results silent :var a=ob-calc-table-1 + inv(a) +#+END_SRC + +#+BEGIN_SRC calc :results silent :var a=ob-calc-table-2 + a*2 - 2 +#+END_SRC + +#+BEGIN_SRC calc :results silent :var a=ob-calc-table-2 + vmean(a) +#+END_SRC + +#+BEGIN_SRC calc :results silent :var a=ob-calc-table-3 + a +#+END_SRC + +#+BEGIN_SRC calc :results silent :var a=ob-calc-table-2 + a +#+END_SRC diff --git a/testing/lisp/test-ob-calc.el b/testing/lisp/test-ob-calc.el new file mode 100644 index 000000000..443ccd64b --- /dev/null +++ b/testing/lisp/test-ob-calc.el @@ -0,0 +1,80 @@ +;;; test-ob-calc.el --- tests for ob-calc.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Visuwesh + +;; Author: Visuwesh + +;; 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 . + +;;; Code: +(require 'ob-calc) + +(unless (featurep 'ob-calc) + (signal 'missing-test-dependency "Support for Calc code blocks")) + +(ert-deftest ob-calc/simple-program-mult () + "Test of simple multiplication." + (org-test-at-id "40e4cd26-fe15-45c0-938b-111e021a5a99" + (org-babel-next-src-block) + (should (equal "2" (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/simple-program-arith () + "Test of simple arithmetic." + (org-test-at-id "40e4cd26-fe15-45c0-938b-111e021a5a99" + (org-babel-next-src-block 2) + (should (equal "27" (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/simple-program-symbolic () + "Test of simple symbolic algebra." + (org-test-at-id "40e4cd26-fe15-45c0-938b-111e021a5a99" + (org-babel-next-src-block 3) + (should (equal "1 / a" (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/matrix-inversion () + "Test of a matrix inversion." + (org-test-at-id "138938e1-f0ba-4c2b-babe-5d20f2b83557" + (org-babel-next-src-block) + (should (equal "[[-1, 0.625, -0.125], [0.25, -0.5, 0.25], [0.5, 0.125, -0.125]]" + (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/matrix-algebra () + "Test of simple matrix algebra." + (org-test-at-id "138938e1-f0ba-4c2b-babe-5d20f2b83557" + (org-babel-next-src-block 2) + (should (equal "[0, 2, 4, 6, 8]" + (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/matrix-mean () + "Test of simple mean of a vector." + (org-test-at-id "138938e1-f0ba-4c2b-babe-5d20f2b83557" + (org-babel-next-src-block 3) + (should (equal "3" + (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/matrix-correct-conv-column () + "Test of conversion of column table to Calc format." + (org-test-at-id "138938e1-f0ba-4c2b-babe-5d20f2b83557" + (org-babel-next-src-block 4) + (should (equal "[[1], [2], [3]]" + (org-babel-execute-src-block))))) + +(ert-deftest ob-calc/matrix-correct-conv-row () + "Test of conversion of row table to Calc format." + (org-test-at-id "138938e1-f0ba-4c2b-babe-5d20f2b83557" + (org-babel-next-src-block 5) + (should (equal "[1, 2, 3, 4, 5]" + (org-babel-execute-src-block))))) + +(provide 'test-ob-calc) +;;; test-ob-calc.el ends here -- 2.43.0