当前位置:必发365电子游戏 > 编程 > 实际不是教你怎样正确地、科学地用java求出函数在有些的导数
实际不是教你怎样正确地、科学地用java求出函数在有些的导数
2019-12-19

先是声美赞臣(Meadjohnson卡塔尔(قطر‎点,本文首要介绍的是面向对象(OO)的思考,顺便谈下函数式编制程序,并不是教您哪些正确地、科学地用java求出函数在有个别的导数。

 

一、引子

 

def d(f) :
    def calc(x) :
        dx = 0.000001  # 表示无穷小的Δx
        return (f(x+dx) - f(x)) / dx  # 计算斜率。注意,此处引用了外层作用域的变量 f
    return calc  # 此处用函数作为返回值(也就是函数 f 的导数)
# 计算二次函数 f(x) = x2 + x + 1的导数
f = lambda x : x**2 + x + 1  # 先把二次函数用代码表达出来
f1 = d(f)# 这个f1 就是 f 的一阶导数啦。注意,导数依然是个函数
# 计算x=3的斜率
f1(3)
# 二阶导数
f2 = d(f1)

首先,直接上大器晚成段python代码,请大家先深入分析下方面代码是用什么艺术求导的。请不要被这段代码吓到,你无需纠葛它的语法,只要驾驭它的求导思路。

以上代码援用自《缘何我推荐 Python[4]:作为函数式编制程序语言的 Python》,那篇博客是促使自个儿写篇作品的重大缘由。

博主说“若是不用 FP,改用 OOP,上述须要该怎么落成?笔者认为啊,用 OOP 来求导,那代码写起来多半是又丑又臭。”

自家半信半疑,于是就用面向对象的java试了试,最终也非常少代码。假如用java8或之后版本,代码越来越少。

请我们想一想叁个题目,怎样用面向对象的思绪改写这些顺序。请先好好动脑,尝试编个程序再持续往下看。

杜撰到见到那一个标题进来的同窗多数是学过java的,下边作者用java,用面向对象的思路一步步深入分析那一个主题材料。

 

二、求导

 

文章起初笔者已近注脚过了,本文不是来谈谈数学的,求导只是自己用来验证面向对象的八个事例。

借使你早就忘了启幕这段代码的求导思路,请回头再看看,看看用python是如何求导的。

深信您只要听别人讲过求导,鲜明一眼就见到初阶这段代码是用导数概念求导的。

必发365电子游戏 1

代码中只是将无穷小Δx粗略地算做四个比较小的值0.000001。

 

三、最先的主张

 

//自定义函数
public class Function {
    //函数:f(x) = 3x^3 + 2x^2 + x + 1
    public double f(double x) {
        return 3 * x * x * x + 2 * x * x + x + 1;
    }
}

//一元函数导函数
public class DerivedFunction {
    //表示无穷小的Δx
    private static final double DELTA_X = 0.000001;
    //待求导的函数
    private Function function;

    public DerivedFunction(Function function) {
        this.function = function;
    }

    /**
     * 获取function在点x处的导数
     * @param x 待求导的点
     * @return 导数
     */
    public double get(double x) {
        return (function.f(x + DELTA_X) - function.f(x)) / DELTA_X;
    }
}

public class Main {
    public static void main(String[] args) {
        //一阶导函数
        DerivedFunction derivative = new DerivedFunction(new Function());
        //打印函数在x=2处的一阶导数
        System.out.println(derivative.get(2));
    }
}

先声贝因美(Karicare卡塔尔(قطر‎点,思考到博客篇幅,笔者利用了不规范的代码注释,希望大家不要被笔者错误的指导。

自家想如若我们能够思考了,应该起码会想到那步吧。代码小编就不解释了,作者只是用java改写了稿子开端的这段python代码,做了贰个简洁明了的翻译职业。再请我们着想下以上代码的主题材料。

刚开首,小编思索那一个题目想开的是建多个名叫Function的类,类中有贰个名称叫f的艺术。但思考到要每一遍必要新的函数导数时就得改变这么些f方法的落到实处,鲜明不方便人民群众增添,那违背了开闭原则。

必发365电子游戏,估量有的同学没听过这些词,我就解释下:”对象(类,模块,函数等)应对扩展开放,但对修改密封“。

于是小编就没继续写下去,但为了让大家直观的感想到那几个主张,笔者写那篇博客时就落到实处了一下以此主见。

请我们动脑一下什么重构代码以缓和扩展性难点。

 

四、开首的主张

 

估摸学过面向对象的同学会想到把Function类改成接口或抽象类,现在每一次增添新的函数时只要重写那一个接口或抽象类中的f方法,那正是面向接口编制程序,符合依赖反转原则,上面包车型大巴代码就是那般做的。

再声称一点,思索到篇幅的标题,后边的代码笔者会省去与后边代码重复的注释,有不知晓的地点还请看看上叁个设法中的代码。

//一元函数
public interface Function {
    double f(double x);
}

//自定义的函数
public class MyFunction implements Function {
    @Override
    public double f(double x) {
        return 3 * x * x * x + 2 * x * x + x + 1;
    }
}

public class DerivedFunction {
    private static final double DELTA_X = 0.000001;
    private Function function;

    public DerivedFunction(Function function) {
        this.function = function;
    }

    public double get(double x) {
        return (function.f(x + DELTA_X) - function.f(x)) / DELTA_X;
    }
}

public class Main {
    public static void main(String[] args) {
        //一阶导函数:f'(x) = 9x^2 + 4x + 1
        DerivedFunction derivative = new DerivedFunction(new MyFunction());
        System.out.println(derivative.get(2));
    }
}

自身想认真看的校友也许会发掘二个标题,作者的翻译做的还不成功,开始这段python代码还足以轻便地求出二阶导函数(导数的导数),而自己的代码却至极。

骨子里只要稍加改正上述代码的一个地点就能够轻易达成求二阶导,请再思量片刻。

 

五、后来的主张

 

当笔者写出地点的代码时,笔者备感完全能够死不认可“用 OOP 来求导,那代码写起来多半是又丑又臭”的意见。但还不可能求二阶导,笔者有一点点不甘心。

于是乎作者就动笔,列了后生可畏晃用定义求生机勃勃阶导和求二阶导的姿势,想了想多少个姿态的分歧与关系,猝然想到导函数也是函数。

DerivedFunction的get方法和Function的f方法的参数和重返值同样,DerivedFunction能够兑现Function接口,于是发出了上面包车型客车代码。

public interface Function {
    double f(double x);
}

public class DerivedFunction implements Function {
    private static final double DELTA_X = 0.000001;
    private Function function;

    public DerivedFunction(Function function) {
        this.function = function;
    }

    @Override
    public double f(double x) {
        return (function.f(x + DELTA_X) - function.f(x)) / DELTA_X;
    }
}

public class Main {
    public static void main(String[] args) {
        Function f1 = new DerivedFunction(new Function() {
            @Override
            public double f(double x) {
                return 3 * x * x * x + 2 * x * x + x + 1;
            }
        });
        System.out.println(f1.f(2));
        //二阶导函数:f''(x) = 18x + 4
        Function f2 = new DerivedFunction(f1);
        //打印函数f(x) = 3x^3 + 2x^2 + x + 1在x=2处的二阶导数
        System.out.println(f2.f(2));
    }
}

构思到一些同学没学过java8或以上版本,以上代码未有运用java8函数式编制程序的新特点。 

设若你接触过java8,请思谋怎么改写以上代码,使其更简明。

 

六、最后的主张

 

public class DerivedFunction implements Function<Double, Double> {
    private static final double DELTA_X = 0.000001;
    private Function<Double, Double> function;

    public DerivedFunction(Function<Double, Double> function) {
        this.function = function;
    }

    @Override
    public Double apply(Double x) {
        return (function.apply(x + DELTA_X) - function.apply(x)) / DELTA_X;
    }
}

public class Main {
    public static void main(String[] args) {
        //打印函数在x=2处的二阶导
        System.out.println(new DerivedFunction(new DerivedFunction(x -> 3 * x * x * x + 2 * x * x + x + 1)).apply(2.0));
    }
}

事情未发生前多少个主见为了扩展Function接口,使用了外界类、佚名类的方式,其实也能够用此中类。而那在这里边,笔者用了lambda表明式,是否更简明了。

此处用的Function接口用的是jdk自带的,大家不供给本人定义了。因为那是叁个函数式接口,我们得以用lambda方便地完成。后来察觉,其实这里用UnaryOperator本条接口更适于。

现行反革命大家有未有开掘,用java、用OOP也足以非常简短地实现求导,并不及发轫的这段python代码麻烦超多。

 

七、编制程序范式

 

以作者之见,编制程序范式简单易行来讲就是编制程序的意气风发种方式,生机勃勃种风格。

自家先介绍此中的几个,你基本上就驾驭它的含义了。

 

7.1 实际不是教你怎样正确地、科学地用java求出函数在有些的导数。面向对象程序设计(OOP)

总的来看此间的同班应该对面向对象有了更加直观的认知。在面向对象编制程序中,万物皆对象,抽象出类的概念。基本特色是包装、继承、多态,认知不深的同校能够再去作者以前的代码中找找那八个特色。

本人早先还介绍了面向对象的多少个尺码:开闭原则、借助反转原则。其余还会有单意气风发任务标准、里氏替换原则、接口隔断原则。那是面向对象的5个主导法规,合称SOLID)。

 

7.2 函数编制程序语言(FP)

本文初步这段代码用的就是python函数式编制程序的语法,后来自家又用java8函数式编制程序的语法翻译了这段代码。

相信您早已直观地心得到它的精短,以函数为主导,几行代码就缓慢解决了求导的难点。

 

7.3 进程式编制程序(Procedural programming)

大致学过编制程序都学过C,C语言正是后生可畏种进度式编程语言。在作者眼里,进程式编程大致正是为了做到叁个急需,像记流水帐相似,平铺直叙下去。 

       

八、结尾

 

由于自身初学java,前段时间只可以想到这么多。如若大家有越来越好的主见依旧觉的自己上边说的不符合规律,招待商议,望各位多多点拨。

这是自个儿的率先篇手艺博客,但愿作者说掌握了面向对象。借使对您有援救,请点个赞只怕商议下,给自身点持续创作的引力。

上一篇:没有了
下一篇:没有了