A short note on short differentiation programs in lisp, and a comment on logarithmic differentiation

Similar documents
CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

Lisp Basic Example Test Questions

Building a system for symbolic differentiation

Symbolic Reasoning. Dr. Neil T. Dantam. Spring CSCI-561, Colorado School of Mines. Dantam (Mines CSCI-561) Symbolic Reasoning Spring / 86

4/19/2018. Chapter 11 :: Functional Languages

Building a system for symbolic differentiation

6.001: Structure and Interpretation of Computer Programs

Modern Programming Languages. Lecture LISP Programming Language An Introduction

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 4. LISP: PROMĚNNÉ, DALŠÍ VLASTNOSTI FUNKCÍ, BLOKY, MAPOVACÍ FUNKCIONÁLY, ITERAČNÍ CYKLY,

Announcement. Overview. LISP: A Quick Overview. Outline of Writing and Running Lisp.

Functional Programming. Contents

Functional Programming. Pure Functional Programming

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

LECTURE 16. Functional Programming

An Explicit-Continuation Metacircular Evaluator

Using Symbols in Expressions (1) evaluate sub-expressions... Number. ( ) machine code to add

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

UMBC CMSC 331 Final Exam

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

CSCI337 Organisation of Programming Languages LISP

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

Common LISP Tutorial 1 (Basic)

A Small Interpreted Language

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

A Quick Introduction to Common Lisp

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

Lambda Calculus see notes on Lambda Calculus

Discussion 12 The MCE (solutions)

6.001 Notes: Section 8.1

Simplifying Logical Formulas

A little bit of Lisp

Functional Programming. Big Picture. Design of Programming Languages

Introduction 2 Lisp Part III

(defun fill-nodes (nodes texts name) (mapcar #'fill-node (replicate-nodes nodes (length texts) name) texts))

Introduction to lambda calculus Part 3

Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

CS 360 Programming Languages Interpreters

Common LISP-Introduction

Lecture Notes on Lisp A Brief Introduction

John McCarthy IBM 704

Functional programming with Common Lisp

Lambda Calculus and Lambda notation in Lisp II. Based on Prof. Gotshalks notes on Lambda Calculus and Chapter 9 in Wilensky.

Well, Hal just told us how you build robust systems. The key idea was-- I'm sure that many of

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Introduction to Functional Programming and basic Lisp

;; definition of function, fun, that adds 7 to the input (define fun (lambda (x) (+ x 7)))

UMBC CMSC 331 Final Exam

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

Control in Sequential Languages

Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Functional Programming. Pure Functional Languages

Functions & First Class Function Values

CS 480. Lisp J. Kosecka George Mason University. Lisp Slides

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

University of Massachusetts Lowell

Review of Functional Programming

UMBC CMSC 331 Final Exam Section 0101 December 17, 2002

Functional Programming with Common Lisp

A Brief Introduction to Scheme (II)

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

Artificial Intelligence Programming

Announcements. Today s Menu

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Functional Languages. Hwansoo Han

COP4020 Programming Assignment 1 - Spring 2011

Robot Programming with Lisp

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

History. Functional Programming. Based on Prof. Gotshalks notes on functionals. FP form. Meaningful Units of Work

Statistics Case Study 2000 M. J. Clancy and M. C. Linn

Imperative, OO and Functional Languages A C program is

Homework 1. Reading. Problems. Handout 3 CSCI 334: Spring, 2012

Midterm Examination (Sample Solutions), Cmput 325

Comp 311: Sample Midterm Examination

B The SLLGEN Parsing System

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

Project 2: Scheme Interpreter

Introduction to Scheme

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

Documentation for LISP in BASIC

CSc 520 Principles of Programming Languages

CS61A Midterm 2 Review (v1.1)

Symbols are more than variables. Symbols and Property Lists. Symbols are more than variables. Symbols are more than variables.

CSCI 3155: Principles of Programming Languages Exam preparation #1 2007

Introduction to LISP. York University Department of Computer Science and Engineering. York University- CSE V.

SCHEME AND CALCULATOR 5b

Common Lisp. Blake McBride

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 2. ÚVOD DO LISPU: ATOMY, SEZNAMY, FUNKCE,

4.2 Variations on a Scheme -- Lazy Evaluation

Introduction to Artificial Intelligence CISC-481/681 Program 1: Simple Lisp Programs

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

STEPHEN WOLFRAM MATHEMATICADO. Fourth Edition WOLFRAM MEDIA CAMBRIDGE UNIVERSITY PRESS

CS A331 Programming Language Concepts

CS 275 Name Final Exam Solutions December 16, 2016

(defmacro while (condition &body body) `(iterate loop () (if,condition (loop)))))

Look at the outermost list first, evaluate each of its arguments, and use the results as arguments to the outermost operator.

ALISP interpreter in Awk

Transcription:

A short note on short differentiation programs in lisp, and a comment on logarithmic differentiation Richard Fateman University of California, Berkeley September, 1998 1 Lisp and differentiation By tradition and design, Lisp is alleged to be a particularly convenient programming language in which to represent algebraic expressions and in which to write a differentiation program. Over the years, most books on Lisp have included programs for differentiation. Some have extended this example to provide fodder for problems for data-directed, functional, object-oriented, rule-based or other styles of programming 1. Since the task of algebraic differentiation can be specified with varying amounts of detail, a programmer typically has options in choosing compromises with respect to size, efficiency, robustness, generality, extensibility, and other issues. Even full-featured computer algebra systems like Maple, Macsyma and Mathematica differ in their built-in ability to compute certain derivatives or represent them operationally. This report has yet another program, one which we wrote to have fun with using logarithmic derivatives for the product rule, and for derivatives of powers. It has a certain charm in being slightly smaller in these parts, and in providing additional challenge for a subsequent simplification step 2. 2 Logarithmic differentiation: the idea If you have forgotten (or never learned) logarithmic differentiation, it is just a way of easing the task of differentiating a messy product of powers by writing it out in a different way. 1 Abelson/Sussman s Structure and Interpretation of Computer Programs is a modern example of this. 2 When I was first hired to teach in a mathematics department and there was a discussion of whether to include computer algebra in a calculus course, some instructors objected on the grounds that something then would have to be left out. I suggested logarithmic differentiation! 1

First, recall that D x log y = (1/y)D x y so that, should you choose to do so, you can compute D x y by the formula D x y = yd x log y. This initially looks like a loser, because you now have to differentiate log y which is more complex than the problem you started with. Here s the trick: if you are given y = u n 1 1 un 2 2 un k k you can use the above formula to decrease the bookkeeping by simplifying log y before doing the differentiation on the right hand side. Recall that log y = n 1 log u 1 + n 2 log u 2 + n k log u k. so that in particular we can write out D x y as D x y = y { n 1D x u 1 + n 2D x u 2 + + n kd x u k }. u 1 u 2 u k The calculus texts assert that this is easier, at least for complicated y, and it is especially true if you can finesse the situation by continuing to use the small symbol y for its longer written-out definition. Logarithmic differentiation suggests a neat formula for differentiation of indexed products of indefinite size: consider the differentiation of This is easily expressed as n p = a i. i=1 D x p = p n i=1 D x a i a i. Mathematica 3.0 doesn t know this formula, although Macsyma 2.2 does. 3 Program complexity and size In this section we describe a simple program to implement this and much of the rest of the algorithm needed. The program, given in full below, does not do much error checking, and no simplification. A differentiation program for a real computer algebra system would rely on substantial simplification programs, and would likely have simplification intertwined with its processing to save time and avoid unnecessarily producing large intermediate expressions. One common optimization might be checking for sub-expressions being free of any dependency on the variable of differentiation, in which case the derivative is 0. A commercial system would most likely provide a set of built-up tools to try to make it easier to add to the program than the rules we have here. 2

Our aim here is to illustrate low complexity judging by number of symbols, functions, and construction, and yet provide a program with modest generality, able to differentiate explicit algebraic expressions written in the usual parenthesized prefix form of lisp. For example, we can differentiate (+ a b c d) and we do not require + and * to be binary-only operators. We allow sin, cos, exp, log, expt and could add other functions easily. We do an indexed product as well. How can we measure the size of a program? We attach a modified text leaving out the comments, shortening arbitrary identifiers to single letters, removing indexed product (since this is somewhat esoteric, and we only included it for fun). We also squeezed out all non-essential white space. We still start each function on a separate line and keep lines to 80 characters. This program is 528 characters (including 38 spaces) on 14 text lines. Not counting punctuation marks, there are 128 tokens. We could, of course, make it smaller by removing more of its capabilities. Using logarithmic differentiation shortens parts of it in minor ways. Since this is not a serious program, it is primarily an illustration of how briefly one can express mathematical ideas, appropriately encoded, as programs. ;; ;; Compute the derivative of expression exp wrt variable var, ;; presuming exp is a conventional lisp expression and var is a ;; symbolic atom (like x). (defun deriv (exp var) (if(atom exp)(if (eq exp var) 1 0) ; dx/dx =1, other atoms 0. ;; data-directed dispatch to a deriv pgm or the undef-deriv pgm (funcall (or (get (car exp) deriv) # undef-deriv) exp var))) (defun undef-deriv (exp var) (derivative,exp,var)) ;unknown fn deriv ;; establish a table of derivatives with appropriate use of ;; the chain rule. ;; Here are well-known functions of a single argument (defun make-diff-rule ;put data-directed chain rules in lisp system (operator stuff) (setf (get operator deriv) (compile () ;convert the lambda expression into a program (lambda (exp var) 3

(let ((arg (cadr exp))) (list * (subst arg arg,stuff) (deriv arg var))))))) (make-diff-rule cos (* -1 (sin arg))) (make-diff-rule sin (cos arg)) (make-diff-rule exp (exp arg)) (make-diff-rule log (expt arg -1)) ;; etc for other 1-argument functions ;; traditional functions of a variable number of arguments: + and * (setf (get + deriv) # (lambda (exp var) (+,@(mapcar # (lambda(r)(deriv r var))(cdr exp))))) ;; the traditional way of generating u*v --> u*v + v*u ;; but generalized to any number of multiplicands (setf (get * deriv) # (lambda (exp var) (+,@(maplist # (lambda(r) ;u *[expression/u] (*,(deriv (car r) var),@(remove (car r) (cdr exp) :count 1))) (cdr exp))))) ;; example ;; (deriv (* a b x) x) ==>(+ (* 0 B X) (* 0 A X) (* 1 A B)) ;; Here s an alternative using "logarithmic derivatives". ;; that says dy/dx = y*d/dx (log(y)). ;; If y is a product u*v, then let us use log(y)=log(u)+log(v) ;; and then dy/dx = y* {(1/u)*du/dx +(1/v)*dv/dx} ;; including generalization to any number of multiplicands. (setf (get * deriv) # (lambda (exp var) (*,exp 4

(+,@(mapcar # (lambda(r) (*,(deriv r var) (expt,r -1))) (cdr exp)))))) ;; same example ;;( deriv (* a b x) ==> ;; (* (* A B X) (+ (* 0 (EXPT A -1)) (* 0 (EXPT B -1)) (* 1 (EXPT X -1)))) ;; a similar "log derivative" view of y=u^v gives dy/dx = y*d/dx(v*log(u)) (setf (get expt deriv) # (lambda(exp var) (*,exp,(deriv (*,(caddr exp) (log,(cadr exp))) var)))) ;;this makes really unsimplified results.. e.g. derivative of x^n produces. ;; (* (EXPT X N) ;; (* (* N (LOG X)) ;; (+ (* 0 (EXPT N -1)) (* (* 1 (EXPT X -1)) (EXPT (LOG X) -1))))) ;;which, if you study it, is a product: ;; n * 1/log(x) * log(x) * x^n * x^(-1) ;;and indeed equivalent to.. (* n (expt x (+ n -1))) ;; ;; And here is a rule that provides us with a capability lacking in ;; Mathematica 3.0 (setf (get product deriv) # (lambda(exp var) (*,exp (sum,(deriv (cadr exp) var),@(cddr exp))))) ;;(deriv (product (a_i x) i=1 y) x) ==> ;;(* (PRODUCT (A_I X) I=1 Y) (SUM (DERIVATIVE (A_I X) X) I=1 Y)) 4 A short version of the program above (defun d(e v)(if(atom e)(if(eq e v)1 0) (funcall(or(get(car e) d)# undef)e v))) 5

(defun undef(e v) (d,e,v)) (defun r(op s)(setf(get op d)(compile() (lambda(e v)(let((x(cadr e))) (list *(subst x x,s)(d x v))))))) (r cos (* -1(sin x))) (r sin (cos x)) (r exp (exp x)) (r log (expt x -1)) (setf(get + d)# (lambda(e v) (+,@(mapcar # (lambda(r)(d r v))(cdr e))))) (setf(get * d) # (lambda(e v) (*,e(+,@(mapcar # (lambda(r) (*,(d r v)(expt,r -1)))(cdr e)))))) (setf(get expt d)# (lambda(e v) (*,e,(d (*,(caddr e)(log,(cadr e)))v)))) (c) 1998 Richard Fateman Appeared in ACM SIGSAM Bulletin volume 32, number 3, September, 1998 issue 125 2 7 6