[MATLAB]多项式类加减乘除

一、 问题描述

创建一个能够进行四则运算的多项式类,要求:
1、 用升幂排列的系数数组表示多项式,p(x)=a0+a1x +a2x2+a3x3表示为p=[a0,a1,a2,a3];
2、 重载四个运算符+、-、*和\。以及定义积分和微分计算

二、 求解思路

对于一个多项式,其最关键的参数为系数和对应自变量的次方,若将多项式的系数按顺序排列,则自动的顺序将代表自变量的次方(规定最右的系数为常数项,从左向右依次递增),则对于多项式的操作完全变为对多项式系数的操作,多项式的加法变为对应系数的相加,多项式的减法变为对应系数的相减,多项式的乘法变为对应系数的卷积,多项式的除法变为对应系数的去卷积,多项式的积分变为将每个系数除以1加上所在自变量次数,并增添一个常数项(默认为1),多项式的微分变为将每个系数乘上所在所在自变量次数。
对于升幂排列,首先需要改变函数Docpolynom,将输出的数组利用fliplr函数反向,然后在已有的降幂排列的char函数基础上,首先在char函数内需要先将输入的系数矩阵利用fliplr函数反向排列,然后在char函数的循环中,将次方的初值设置为0,然后递增。
对于多项式的加法,需要先求出两者的最高项数的差,将项数低的一个多项式系数数组的高次由0填充(放置于原有数组后),然后将两个多项式系数数组相加
对于多项式的减法,与前文的加法做同样处理后,只需将两个多项式系数数组相减即可完成。
对于多项式的乘法,首先定义一个全为0,长度为输入的两数组长度减1的列向量(new),然后利用循环,对于列向量的每一位,将输入两数组的位次(j,k)之和-1等于列向量位数(i)的系数之积(aiaj)相加 (aiaj)既是所需要的列向量的值。
对于多项式的除法,首先需要将输入的数组利用fliplr反向,然后记录下两者的最高项数s1,s2,如果s1<s2,则输出结果为0,否则所得到的结果系数数组为一个长度为(s1-s2+1)的列向量,开始循环,利用find函数,此函数返回数组中所有不为0的位置,定义m为第一个不为0的位置,如果m不大于0,则说明已经结束,退出循环,然后判断系数长度是否小于被除的系数长度,如果小于,则退出循环,如果循环继续,则将被除项的最高次系数除以除项的最高次系数,得到new(i),然后将原有系数组减去(new(i)原有系数组),得到新除后的余数,进行下一次的循环,直到退出或结束循环
对于多项式的积分,定义新的常数项为1,则将其他的项数的系数除以所在项数次数加一则得到新的项数的系数。
对于多项式的微分,将定义一个比微分前的项数少一的列向量,新的列向量的第i位的系数为原多项式第i+1位系数
所在的项数次数

三、 程序代码

classdef DocPolynom
    % file: @DocPolynom/DocPolynom.m, define a polynomial class
    % Public properties
    %四则运算,导数,积分
    properties
        coef = [];   % double vector of polynomial coefficients [highest order ... lowest order]
    end
    
    % Class methods
    methods
        function obj = DocPolynom(c)
            % Construct a DocPolynom object using the coefficients supplied
            if isa(c,'DocPolynom')
                obj.coef = c.coef;
            else
                obj.coef = c(:).';  % c(:) is always a column vector, no matter whether c is an array or matrix.
            end     %把c变成一个列向量
            obj.coef=fliplr(obj.coef);
        end % DocPolynom
        
        function c = double(obj)
             c=double(obj.coef);
        end % double
        
        function s = char(obj)
            % Created a formated display of the polynom
            % as powers of x
            obj.coef=fliplr(obj.coef);
            if all(obj.coef == 0)
                s = '0';
            else
                d = 0;  %修改d的初值
                s = [];
                for a = obj.coef;
                    if a ~= 0;
                        if ~isempty(s)
                            if a > 0
                                s = [s ' + '];
                            else
                                s = [s ' - '];
                                a = -a;
                            end
                        end
                        if a ~= 1 || d == 0
                            s = [s num2str(a)];
                            if d > 0
                                s = [s '*'];
                            end
                        end
                        if d >= 2
                            s = [s 'x^' int2str(d)];
                        elseif d == 1
                            s = [s 'x'];
                        end
                    end
                    d = d+1; %d递增
                end
            end
        end % char
        
        function disp(obj)
            % DISPLAY
            disp(['     ' char(obj)])
        end % disp
        
        function b = subsref(a,s)
            % SUBSREF Implement obj([1 ...]),  a special subscripted assignment
            switch s.type
                case '()'
                    ind = s.subs{:};
                    for k = 1:length(ind)
                        b(k) = eval(strrep(char(a),'x',num2str(ind(k))));
                    end
                case '.'
                    switch s.subs
                        case 'coef'
                            b = a.coef;
                        otherwise
                            error(['''' s.subs '''' ' is not a DocPolynom property'])
                    end
                otherwise
                    error('Specify value for x as obj(x)')
            end
        end % subsref
        
        function r = plus(obj1,obj2)
            % PLUS  Implement obj1 + obj2 for DocPolynom
            obj1 = DocPolynom(obj1);
            obj2 = DocPolynom(obj2);
            k = length(obj2.coef) - length(obj1.coef);
            r = DocPolynom([obj1.coef zeros(1,k) ] + [obj2.coef zeros(1,-k)]);
        end % plus
        
        
        function r = mtimes(obj1,obj2)
            % MTIMES   Implement obj1 * obj2 for DocPolynoms.
            obj1 = DocPolynom(obj1);
            obj2 = DocPolynom(obj2);
            s1=length(obj1.coef);
            s2=length(obj2.coef);
            new=zeros(s1+s2-1,1);
%             r = DocPolynom(conv(obj1.coef,obj2.coef));  %conv返回卷积
            for i=1:s1+s2-1
                for j=1:s1
                    for k=1:s2
                        if (j+k-1)==i
                            new(i)=new(i)+obj1.coef(j)*obj2.coef(k);
                        end
                    end
                end
            end
            r=DocPolynom(new);
        end % mtimes
        
        function r = minus(obj1,obj2)
            % PLUS  Implement obj1 - obj2 for DocPolynom
            obj1 = DocPolynom(obj1);
            obj2 = DocPolynom(obj2);
            k = length(obj2.coef) - length(obj1.coef);
            r = DocPolynom([obj1.coef zeros(1,k)] - [obj2.coef zeros(1,-k)]);
        end % minus
        
        function r = mrdivide(obj1,obj2)
            % MRDIVIDE  Implement obj1 / obj2 for DocPolynom 
            obj1 = DocPolynom(obj1);
            obj1.coef=fliplr(obj1.coef);
            obj2 = DocPolynom(obj2);
            obj2.coef=fliplr(obj2.coef);
            s1=length(obj1.coef);
            s2=length(obj2.coef);
            if s1<s2
                new=0;
            else
                new=zeros(s1-s2+1,1);
                for i=1:s1-s2+1
                    index=find(obj1.coef);
                    if length(index)>0
                       m=index(1);
                    else
                        break;
                    end
                    if s1-m+1<s2
                        break;
                    end
                    new(i)=obj1.coef(m)/obj2.coef(1);
                    rs=zeros(1,s1);
                    for k=m:m+s2-1
                        rs(k)=obj2.coef(k-m+1);
                    end
                    obj1.coef=obj1.coef-new(i)*rs;
                end
            end
            newnew=fliplr(new');
            r=DocPolynom(newnew);

%          r = DocPolynom(fliplr(deconv(obj1.coef,obj2.coef)));  %conv返回去卷积


        end % mrdivide
        
        function r=int(obj1)
            %integral
            obj1 = DocPolynom(obj1);
            n=length(obj1.coef);
            new_n=ones(n+1,1);
            for i=2:n+1
                new_n(i)=obj1.coef(i-1)/(i-1);
            end
            r=DocPolynom(new_n);
        end
        
        function r=diff(obj1)
            %differential
            obj1 = DocPolynom(obj1);
            n=length(obj1.coef);
            new_n=zeros(n-1,1);
            for i=2:n
                new_n(i)=obj1.coef(i)*(i-1);
            end
            r=DocPolynom(new_n);
        end
        
        function y = polyval(obj,x)
            % POLYVAL  POLYVAL(obj,x) evaluates obj at the points x.
            y = 0;
            for a = obj.coef
                y = y.*x + a;
            end
        end % polyval   
    end % methods

end % classdef


clear;
clc;
p1=DocPolynom([1,2,3]);
disp('第一个多项式:')
disp(p1)
p2=DocPolynom([0,1,2,3]);
disp('第二个多项式:')
disp(p2)
disp('多项式的和:');
disp(p1+p2)
disp('多项式的差:');
disp(p1-p2)
disp('多项式的商:');
disp(p2/p1)
disp('多项式的积:');
disp(p1*p2)
disp('多项式积分:');
p1=int(p1);
disp(p1)
disp('多项式微分:');
p1=diff(p1);
disp(p1)

四、 实验结果

如图,输入[1,2,3]输出1+2x+3x2,输入[0,1,2,3],输出x+2*x2+3*x^3,两者的和以及差如图所示,二式除以一式的结果如图,,对第一个多项式积分,输出结果如图,对积分后的 式子微分,结果如图所示

在这里插入图片描述

五、 实验心得

  1. 对于新的概念注意学习已有的模板
  2. 对于复杂的事物必须抓住事物的关键,由浅入深
  3. 类操作是面向对象的编程,一个类中首先定义变量,随后定义各类方法,定义一个类后,可以用定义的各种方法直接操作变量,在某些情况下,能够大大的提高效率。
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值