博主头像
zzh

ワクワク

2.3.2实例:符号求导

像之前一样,我们先假设已经有了一种表达代数表达式的方式,同时有相应的构造函数,选择函数和谓词。在此基础上根据求导法则完成符号求导的操作。做完这些后,我们再去实现代数表达式的定义与其支持的操作。完成这些还不够,使用的效果不如预期,这也是因为表达式是需要化简的。为了实现化简,我们对求和&&求乘积的方法进行修改。以上是整体的思路,接下来是代码的具体实现。

#lang sicp
(define (deriv exp var);;求导的方法,需要参数有表达式和变量
  (cond ( (number? exp) 0);;如果表达式是一个数,求导为0
        ((variable? exp)  ;;如果表达式是变量(不是数),分情况讨论
         (if (same-variable? exp var) 1 0));;表达式是否与变量相同
        ((sum? exp);;如果为和式,分别求导再求和
         (make-sum (deriv (addend exp) var)
                   (deriv (augend exp) var)
                   ))
        ((product? exp);;如果为乘积,自己查数学求导方法
         (make-sum (make-product
                    (multiplier exp)
                    (deriv (multiplicand exp) var))
                   (make-product
                    (multiplicand exp)
                    (deriv (multiplier exp) var))
                   ))
         (else
          (error "error expression type" exp))
         ))
         
         ;;以上是求导程序。下面完善具体实现
         
(define (variable? exp);;判断是否是变量
  (symbol? exp))
  
(define (same-variable? ex1 ex2);;判断两个变量是否相同
  (and (variable? ex1) (variable? ex2) (eq? ex1 ex2)))

(define (make-sum a1 a2);;表达式求和
  (cond ((=number? a1 0) a2)
        ((=number? a2 0) a1)
        ((and (number? a1) (number? a2)) (+ a1 a2))
        (else (list '+ a1 a2))))

(define (=number? a int);;判断表达式是否等于一个数
  (and (number? a) (= a int)))


(define (sum? exp);;是否为和式
  (and (pair? exp) (eq? (car exp) '+)))
(define (addend exp);;取出第二个加数
  (cadr exp))
(define (augend exp);;取出第一个加数
  (caddr exp))
(define (product? exp);;判断乘式
  (and (pair? exp) (eq? (car exp) '*)))
 
(define (make-product a1 a2);;表达式求乘积
  (cond ((=number? a1 0) 0)
        ((=number? a2 0) 0)
        ((=number? a1 1) a2)
        ((=number? a2 1) a1)
        ((and (number? a1) (number? a2)) (* a1 a2))
        (else (list '* a1 a2))))

(define (multiplier exp);;取出第一个乘式因子
  (cadr exp))
(define (multiplicand exp);;取出第二个乘式因子
  (caddr exp))

;;测试用例
(deriv '(+ x 3) 'x)
(deriv '(* (* x y) (+ x 3)) 'x)
        
        
2.3.2实例:符号求导
https://zzhygs.cn/index.php/archives/37/
本文作者 zzh
发布时间 2024-09-16
许可协议 CC BY-NC-SA 4.0
发表新评论