精华内容
下载资源
问答
  • 1引言在现代数学中,线性映射(也称为线性变换或在某些情况下称为线性函数)是两个模(例如,两个向量空间)之间的映射 ,其保持加法运算和标量乘法。如果线性映射是双射,则称为线性同构。线性映射始终将线性子空间映射...

    1引言

    在现代数学中,线性映射(也称为线性变换或在某些情况下称为线性函数)是两个模(例如,两个向量空间)之间的映射 ,其保持加法运算和标量乘法。如果线性映射是双射,则称为线性同构。

    线性映射始终将线性子空间映射到线性子空间,不过注意,可能会映射到较低维的子空间;例如,它可以将过原点的平面映射到平面、直线或者点。

    线性映射通常可以表示为矩阵,简单例子包括旋转和反射线性变换。

    例子

    我们考虑函数 的具体例子。

    例如,函数 是一个线性映射。此函数将向量的 分量放大到原来的 2 倍。对应下面的图,

    42efee2985ff9ce20f3d9fdd96c77d69.gif

    这个函数 有个特点: 无论是先向量相加再对结果向量作映射,还是先映射再把结果向量相加,得到的结果一样。即有

    c4535e65eba9940967eff20c2302a414.gif

    函数 还满足齐次性: 不管是先缩放向量后映射,还是先映射后再缩放,结果相同。即有

    983747d9a6e2e751323c1e45ae07980a.gif

    2凯莱与矩阵

    阿瑟·凯莱(Arthur Cayley)被公认为矩阵论的奠基人。他表明,先前研究的用于二次形式和线性变换的系数阵列是其一般概念的特例。矩阵代数是在凯莱 1855 年左右的研究工作发展而来的。凯莱研究了线性变换的复合,并由此定义了矩阵乘法,以便复合变换的系数矩阵 刚好为矩阵 乘以矩阵 的乘积。

    首先,凯莱将一个 矩阵记为,

    24af9e9486830faf96ab87adea7a0db5.png

    它是一个数字阵列,对应如下线性方程组,

    fdffb2145e8524d313fb8b33abd8c551.png

    用矩阵改写上面的线性方程组,

    97d260eb4d6a5e505be765eacebe7552.png

    也可以这么来看,将如下 3 个线性函数

    89983d1e89c2d1fb3909ff95c163c995.png

    改为矩阵形式(注意,此处还没有向量的概念)

    18286da1d33b676c7138e724cdeec874.png

    上面 3 个函数其实就是 3 个数,分别用大写的 表示并放在一起,那三个线性函数就变成了,

    ef4103f5c446000314779c94ef8bfd9c.png

    凯莱认为,这个公式蕴含了矩阵理论中的很多基本概念。从现在的角度看,这就是 的一个线性变换,

    接着,我们来看两个线性变换的复合,

    b1ec58b40538a95628978eca92314668.png

    这两个线性变换分别从 变换到 以及从 变换到 。将它们写在一起就是由 变换到

    0a6b76f9672c1877c7cf8c1297e62c6d.png

    复合线性变换对应的矩阵是,

    45c71798f208256c0f9beebbc58cf51a.png

    那么这些数字具体是多少呢?将线性方程组的公式代入很容易得到,

    c5d3d80bf2c5b9c657afa45ea795cb99.png

    以上就是两个矩阵复合的规则,也是我们现在线性代数书上定义的矩阵乘法。要注意的是,该运算一般情况下是不可交换的,说明线性变换的复合是跟次序有关系的。

    可以看到,凯莱把线性方程组看成线性变换,提取出矩阵并从复合线性变换的角度定义矩阵乘积。

    用矩阵表示线性变换,这不仅开启了矩阵代数,甚至某个角度也可以说为群表示论啥的埋下了种子。

    3定义与实例

    我们来看两个向量空间之间的线性变换(或线性映射,线性函数或线性算子)的基本定义。

    注意,有些资料会说向量空间到自身的映射叫变换,但这里我们并不采用这种说法。

    定义

    为向量空间。当且仅当对所有 和所有 ,下式

    均成立时, 才是线性变换。

    向量空间 称为变换 的域(domain),而其映射到的空间 称为陪域(co-domain)

    例子

    ,并取 ,然后取定

    定义

    线性变换的矩阵表示

    具有特定基底的向量空间之间的线性变换可以方便地以矩阵形式表示。具体来说,假设 是线性的,并且进一步假定 分别是 的基。

    然后,矩阵 Mat (相对于 在给定基底下线性变换 的矩阵表示)的第 列是 相对于 的表示。

    换一句话说,可以用矩阵

    表示线性变换 ,因为

    其中 ,而

    的第 列。注意 Mat 取决于 特定的基。

    对任意向量 的作用可以从 对于一组基的作用唯一地确定。

    任意向量 ,我们有

    由于 是任意的,可得对于基 ,线性变换 的矩阵为 。将 既视为矩阵又视为从 的线性转换通常不会引起混淆。

    实例解析

    看下面的图,假设这是一个将 2D 平面映射到 3D 空间中某个平面的线性映射。

    8df378cb9f38589a89095eac895b4a84.png

    映射 将 2D 平面的自然基底 分别映射到 3D 空间中的向量 。2D 平面中一个向量 被映射到

    那么请问,在两个空间的自然基底下,这个线性映射可以用一个矩阵表示。那么,请问这个矩阵是?

    可见,这个矩阵就是由两列 构成的矩阵

    打个比方,映射就好比红娘,专门为两个空间里的某些向量牵线找对象。我们只要给 2D 平面的自然基底 在 3D 空间中分别找到对象,例如,。然后,这个线性映射就确定了,而 2D 平面上其余向量也就自然而然地找到对象了。

    稍微发散一下,这里有很大空间可以发挥你的想象力。

    例如,给 找的对象是同一个,即 。那么会发生些什么呢?

    假如,2D 平面的基不取自然基底,而是其他基,如一组标准正交基 ?那么此时,这个线性映射如果用矩阵表示的话,这个矩阵会是什么呢?

    4与 SVD 的联系

    用矩阵表示,自然就是将一个空间中的某个向量在某组基下的坐标,然后通过矩阵-向量乘法将其转换为另一个空间中的向量坐标。

    即用矩阵表示坐标向量之间的转换,如 ,这里 都是在各自坐标系下的坐标。

    对任意向量 的作用由它对于一组基的作用唯一地(由线性)确定。

    我们考虑上文中那个将 2D 平面映射到 3D 空间中某个平面的线性映射。

    矩阵 的 SVD 分解为

    对于任意向量 ( 是任意的,因此  也是任意的),则有

    由于 是任意的,可得在 以及 基底下,这个线性映射就是,

    此时,这个线性映射的矩阵非常简单,那就是一个对角矩阵

    好了,从这个例子可以看到: 可以用矩阵表示两个线性空间之间的变换,而矩阵的 SVD 分解给出了两个空间的特殊的基底,从而简化这个线性变换的矩阵形式。

    这就是矩阵 SVD 分解的巧妙之处,关于它,这里点到为止,具体内容以及相应图解将在后期展开。

    相关阅读

    矩阵和线性代数原来是这么来的

    概率论原来可以这样优雅地入门

    机器学习的数学基础 之 向量范数

    机器学习的数学基础 之 矩阵范数

    矩阵特征值的故事 - 缘起琴弦

    矩阵前传 - 消元法与行列式之独立演义矩阵前传 - 牛顿没带红的货被高斯带红了矩阵前传 - 克莱姆没能证明的法则被他两行搞定矩阵前传 - 矩阵之父 Sylvester 为什么提出 Matrix矩阵前传 - 柯西-比内公式及其用初等矩阵的证明二次型和矩阵合同原来是这么一回事

    拉格朗日乘子法的来历与直观解释

    矩阵特征值是这么来的,以及有趣的盖尔圆矩阵分解术,不得不从高斯说起万能的 SVD 分解是哪位牛人提出来的?

    度量、范数和内积原来是这么个关系

    7815763973a2550deb00dda213cd5ae3.png

    展开全文
  • 目录:containers.Map,tables,enumeration和time series...containers.Map简介MATLAB中最具代表性的高级数据类型是containers.Map,我们可以把它叫做映射表。它和函数映射有些类似,比如函数映射的定义是:F(x) =...

    目录:

    containers.Map,tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算使用。本篇首先介绍 containers.Map 数据类型。

    containers.Map简介

    MATLAB中最具代表性的高级数据类型是containers.Map,我们可以把它叫做映射表。它和函数映射有些类似,比如函数映射的定义是:

    F(x) = Y

    针对每一个X,都有一个唯一的Y与之对应,反之不一定。如图Fig.1所示。和函数映射相似,映射表用来形容键(Key)和键值(Key Value)之间的一一对应关系。每个Key都是独一无二的,且只能对一个Key Value。如图Fig.2所示。

    Fig.1 函数映射关系

    Fig.2 containers.Map类的映射示意图

    数组,元胞和结构体的局限性

    开始我们先介绍一下数组,元胞数组和结构体的局限性,为什么有的时候这些基本的数据类型无法满足程序的要求,换句话说,我们为什么需要 containers.Map 数据结构。假设要用MATLAB来记录电话号码簿中数据,比如表Table.1所示:

    Table.1 电话号码簿姓名

    电话号码

    Abby

    5086470001

    Bob

    5086470002

    Charlie

    5086470003

    先讨论数组,因为电话号码簿中既含有数字,又含有字符串,而数组中只能存放Double类型的数据,所以没有办法用数组直接记录电话号码薄中的内容。

    再试试元胞数组,我们在第1行预先声明一个 3 X 3的元胞数组,然后在2-4行按顺序填放号码簿的内容。

    % 元胞数组初始化

    addressBook = cell(3,1); % 预分配大小是MATLAB编程的好习惯

    addressBook{1} = {'Abby', '5086470001'};

    addressBook{2} = {'Bob' , '5086470002'};

    addressBook{3} = {'Charlie', '5086470003'};

    需要的时候,可以通过for循环访问其中的内容,比如:

    for iter = 1:length(addressBook) % 元胞数组的遍历

    addressBook{iter}          % 通过Index访问元胞中的内容

    end

    但是按照顺序遍历电话号码簿没有什么实际用处,号码簿的主要功能应该是提供查找的功能才是。比如要想查询Charlie的电话号码,我们希望程序最好可以写成如下这样:

    CharlieNum = addressBook{'Charlie'} % 提示:这是错误的写法

    或者

    CharlieNum = addressBook.Charlie % 提示:这是错误的写法

    但是元胞数组的值只能通过Index去访问内容,不支持如上的访问方式。所以为了找到Charlie的电话号码,程序不得不遍历元胞中的所有内容,取出每一个元胞元素的第一列的字符串做比较,如果名字等于Charlie,则输出电话号码:

    % 使用for循环查找

    for iter = 1:length(addressBook)

    if strcmp(addressBook{iter}{1},'Charlie')

    addressBook{iter}{2} % 如找到则输出电话号码

    break;

    end

    end

    当然还有其他的方式来盛放电话号码簿,比如把电话和名字分别存到到两个元胞数组中去

    names = {'Abby','Bob','Charlie'}; % 用元胞放号码

    numbers = {'5086470001','5086470002','5086470001'}; % 用元胞放名字

    ind = find(strcmp(names,'Charlie')); % strcmp接受向量的输入 返回Logical数组

    % find紧接着找出逻辑数组中非零元素的Index

    numbers{ind}

    其中第3行strcmp接受元胞作为输入,在其中寻找Charlie,find函数将返回Charlie所在的位置,这样的方式比使用for循环要快,但无一例外的是,两种方法都要从头开始遍历一个数组,终究来说是慢的。

    除查找性能慢外,使用元胞盛放电话号码簿类型的数据还有其它缺点:

    无法方便的验证重复数据。电话号码簿要求每一个人的名字都是独一无二的,所以在数据录入的时候要防止姓名的重复,但是我们没有其它办法知道某名字是否已经被使用过了,除非在每次输入的时候都对整个元胞里的内容做遍历比较。

    无法方便地添加内容。如果电话号码簿中的记录需要不断地增长,但是我们没有办法在一开始就估计出其大概的数量,于是无法有效的预先分配内存,所以添加数据时,一旦超过预先分配的量,MATLAB就要重新分配内存了。

    无法方便地删除内容。如果我们要从元胞中去掉某一记录,可以找到该记录,并把该位置的元胞内容置空,但这并不会自动减小元胞数组的长度,如果

    这样的删减操作多了,元胞中会留下很多没有利用的空余位置。

    不方便作为函数的参数,具体原因见struct的局限性.

    最后我们再尝试一下用结构体盛放电话号码簿数据类型,struct的赋值很简单,比如可以直接赋值:

    % 赋值方法1

    addressBook.Abby = '5086470001';

    addressBook.Bob = '5086470002';

    addressBook.Charlie = '5086470003';

    或者:

    % 赋值方法2

    addressBook = struct('Abby','5086470001','Bob','5086470002','Charlie','5086470003')

    方法1和方法2是等价的。

    struct数据类型的查找很方便,比如要查询Charlie的电话号码,直接访问struct中的同名的field即可以了。

    num = addressBook.Charlie

    如果要查询的人名是一个变量, 我们可以使用getfield函数:

    num = getfield(addressBook,name) % 其中name是变量

    struct盛放电话号码簿类型的数据,查询起来确实比元胞进步了不少,但还是有些不方便的地方。

    因为struct的field的名字要求必须是以字母开头,这是一个很大的局限,并不是所有的类似电话号码簿的结构都可以用人名做索引,比如账户号码簿,股票代码等等,他们通常是用数字开头的,比如图Table.2中的数据:

    Table.2 深证股票代码股票代码

    股票名称

    000001

    深发展

    000002

    万科

    000004

    ST国农

    如果我们要求通过股票的代码来查找股票的具体信息,struct无法简单的直接做到。

    使用struct的另一个不方便之处在于,当把struct当做函数参数,并且在函数内部需要对该struct做一定的修改时,为了要把修改后的结果返回,我们需要对原来的struct做完全的拷贝,显然如果struct中的数据很多的话,这样做是低效的。比如下面的函数中,addressBook被当做函数的参数传入,在函数中添加了一个新的field, 为了返回更新后的结构,函数内部必须重新构造一个新的struct,也就是s返回给该函数的调用者。

    % 把struct当做函数的参数

    function s = modifystruct(s)

    s.Dave = '5086470004';

    end

    用containers.Map来记录电话号码簿

    上面一节我们介绍了数组,元胞数组和结构体在模拟电话号码簿这种数据结构时的局限性,这节我们来看怎么用 containers.Map 来盛放电话号码簿中的内容:

    addressMap = containers.Map; % 首先声明一个映射表对象变量

    addressMap('Abby') = '5086470001';

    addressMap('Bob') = '5086470002';

    addressMap('Charlie') = '5086470003';

    第一行我们声明一个containers.Map的变量(其实是containers.Map类的对象)叫做addressMap,2,3,4行通过提供Key Key Value的方式来给对象赋值,其中单引号内部的值叫做键(Key),等式右边的叫做键值(Key Value)。通过这个结构,我们在MATLAB内存中,建立起了如图Fig.3的映射关系数据结构。

    Fig.3 电话号码簿映射表

    Fig.4 Map类的UML

    查找addressMap对象中的内容极其方便,比如查找我们想知道Charlie的电话号码,只需:

    % 查找

    num = addressMap('Charlie')

    如果我们要修改Charlie的电话号码,只需 :

    % 赋值

    addressMap('Charlie') = newNum;

    什么是containers.Mapcontainers.Map是一个MATLAB的内置类(类是面向对象编程中的一个基本概念,在这里可以把类暂时理解成一种数据类型),所谓内置,就是MATLAB内部实现的,通常这种类的性能更加的优秀。containers.Map其中containers是Package的名称,Map是该Package中的一个类,Map是它的类名。用UML(Unified Modeling Language)的语法把该类表示出来,它的属性包括Count, KeyType,ValueType。它的常用方法包括keys,values,isKey,remove。如图Fig.4所示。

    containers.Map的属性和成员方法

    这节我们介绍containers.Map的属性和成员方法,假设我们这样初始化一个containers.Map对象:

    % 初始化一个Map对象

    addressMap = containers.Map;

    addressMap('Abby') = '5086470001';

    addressMap('Bob') = '5086470002';

    addressMap('Charlie') = '5086470003';

    在命令行中键入该对象的名称,MATLAB会显示该对象属性的基本信息:

    >> addressMap

    addressMap =

    Map with properties:

    Count: 3 % MAP 中映射对的数目

    KeyType: char % MAP 中键的类型

    ValueType: any % MAP 中键值的类型

    其中Count 表示Map对象中映射对的数目。按照规定,键的类型一定要是字符类型,不能是其它数据类型,而键值的类型可以是MATLAB中的任意类型:数组,元胞,结构体,MATLAB对象,甚至JAVA对象等等。因为键值的类型可以是任何MATLAB类型,所以 containers.Map 是MATLAB中极其灵活的数据类型。

    成员方法keys 用来返回对象中所有的键:

    >> addressMap.keys

    ans =

    'Charlie' 'Abby' 'Bob'

    成员方法values用来返回对象中的所有键值

    >> addressMap.values

    ans =

    '5086470003' '5086470001' '5086470002'

    remove用来移除对象中的一个键-键值对,经过下面的操作之后,该对象中的Count的值变成了2。

    >> addressMap.remove('Charlie')

    ans =

    Map with properties:

    Count: 2 % 映射对数目减少

    KeyType: char

    ValueType: any

    isKey成员方法用来判断一个map对象中是否已经含有一个键值,比如:

    >> addressMap.isKey('Abby')

    ans =

    1

    >> addressMap.isKey('abby') % 键是大小写敏感的

    ans =

    0

    isKey的功能是查询,类似之前提到的find和strcmp函数合起来使用的例子。

    containers.Map的特点

    containers.Map可以不断地扩张不需预分配

    使用数组和元胞数组作为数据容器,通常要预先分配容器的大小。否则每次扩充容器,MATLAB都会重新分配内存,并且拷贝原来数组中的数据到新分配的内存中去。映射表是一个可以灵活扩充的容器,并且不需要预分配,每次往里面添加内容不会引起MATLAB重新分配内存。

    我们可以通过提供两个元胞来构造映射表对象,比如下面我们构造一个机票簿数据结构:

    % 映射表的初始化方法1

    ticketMap = containers.Map( {'2R175', 'B7398', 'A479GY'}, ...

    {'Abby', 'Bob, 'Charlie'});

    也可以在程序的一开始,先声明一个对象:

    % 映射表的初始化方法2

    >> ticketMap = containers.Map

    然后在计算的过程中慢慢的向表中插入数据:

    % 映射表的初始化方法2

    >> ticketMap['2R175'] = 'Abby';

    ...

    >> ticketMap['A479GY'] = 'Charlie;

    containers.Map可以作为参数在函数内部直接修改

    因为containers.Map是handle类(handle类的介绍参见《MATLAB面向对象编程-从入门到设计模式》第三章:MATLAB的句柄类和实值类),我们还可以方便的将这个对象传给任何MATLAB的函数,并且在函数内部直接修改对象内部的数据,并且不用把它当做返回值输出,比如:

    >> modifyMap(ticketMap);

    modifyMap函数可以写成:

    function modifyMap(ticketMap) % 该函数没有返回值

    .....

    ticketMap(NewKey) = newID

    end

    注意这里没有把修改的ticketMap当做返回值,在函数中我们直接修改了Map中的数据,这是MATLAB面向对象语言中handle类的特性。

    containers.Map可以增强程序的可读性

    映射表内部可以存储各种类型的数据,并且给它们起一些有意义的名字。具体的例子见元素周期表的例子。

    访问和修改这些数据的时候,可以直接使用这些有意义的名字,从而增加程序的可读性。而如果用元胞数组存储这些数据,在访问和修改这些数据的时候, 需要使用整数的Index,程序可读性不够好。

    containers.Map提供对数据的快速查找

    映射表查找的复杂度是常数O(C)的,而传统的数组和元胞数组查找的复杂度是线性O(N)的。如果不熟悉算法中复杂度的概念,可以这样理解:如果使用数组或者元胞来存储数据,当我们要在该数据结构中搜索一个值时,只能做线性搜索,平均下来,搜索的时间和该数据结构中的元素的数目N成正比,即元胞和数组中的元素越多,找到一个值所用的时间就越长,这叫做线性的复杂度 O(N)。而映射表采取的底层实现是哈希表(Hash Map),搜索时间是常数C,理论上来说搜索速度和集合中元素的个数没有关系。所以当容器中元素数量众多的时候,要想查找得快,可以使用containers.Map结构。具体例子见快速查找的例子。

    下面通过对假想的数据集合进行查找,来比较一下数组和container.Map的性能。我们第一行先构造一个含有1000000(10^7)个整数的数组(这是数组中元素的个数很多,如果只有少量元素,线性查找的效率会高一些),按顺序填充从1到(10^7)的整数;作为比较,第二行再构造一个containers.Map对象,往内部填充从1到(10^7)的整数,Key和KeyValue都相同。

    a = 1:1000000;

    m = containers.Map(1:1000000,ones(1,1000000));

    数组数据结构,使用find函数依次查找从1到(10^7)的整数,在笔者的机器上,耗时28.331901秒

    % array的查找

    tic

    for i=1:100000,

    find(b==i);

    end;

    toc

    % command line结果

    Elapsed time is 28.331901 seconds.

    containers.Map数据结构,使用键值1到(10^7)进行访问,

    在笔者的机器上,耗时只需1.323007秒,

    结论是:如果有大量的数据,并且要频繁的进行查找操作,可以考虑使用containers.Map数据结构。(读者可以试试减少容器中元素的个数,观察一下什么情况下,数组的查找会更快一些。)

    % 映射表的查找

    tic

    for i=1:100000,

    m(i);

    end;

    toc

    % command line结果

    Elapsed time is 1.323007 seconds.

    谈到在MATLAB中使用高级数据结构,另一种常见的做法是直接使用Java和Python对象,这里顺便比较一下在MATLAB中使用Java的哈希表的效率。再笔者的机器上,耗时3.072889秒.

    % JAVA哈希表的查找

    s = java.util.HashSet();

    for i=1:100000, s.add(i); end

    tic;

    for i=1:100000,

    s.contains(i);

    end;

    toc

    % command line结果

    Elapsed time is 3.072889 seconds.

    containers.Map的使用实例

    用来盛放元素周期表

    工程计算中可以使用这种键-键值的例子有很多。比如物理化学计算中可以用映射表来盛放元素周期表中的内容:

    >> ptable = containers.Map;

    >> ptable('H') = 1 ;

    >> ptable('He') = 2 ;

    其中键是原子符号,而键值是原子量。因为键值的类型不限,所以键值本身还可以是对象,比如Atom类对象,其中包涵更多有用的内容:

    % 类文件Atom.m

    classdef Atom < handle

    properties

    atomicNumber

    fullName

    end

    methods

    function obj = Atom(num,name)

    obj.atomicNumber = num ;

    obj.fullName = name

    end

    end

    end

    \end{Verbatim}

    于是:

    % 键值可以是Atom对象

    >> ptable('H') = Atom(1,'hydrogen');

    >> ptable('H') = Atom(2,'helium');

    用来实现快速地检索

    这个问题来自ilovematlab一个网友的提问:

    大家好,最近遇到一个问题,要构建20000次以上的三元素向量,且保证每次不重复构建,该向量元素值在2000―3000之间不定数,目前采用的方法是建立一历史档案矩阵A,构建一个存储一行,A大小行数持续增加。每次在构建出一新的向量时对该向量与历史档案矩阵每行进行对比,最终确定是否构建过,若没构建过,重新构建。算法显示该检查程序运算时间在执行20000次以上时,会超过200S的运行时间。想力争减小该时间,求方法。

    多谢!

    这位网友的问题不在于如何构建这些向量,而是如何保证每次不重复的构建。他一开始想出的解决方法是用矩阵A来存储历史档案,每建立一个新的向量,和该历史档案已有的内容做比较,如果在档案中没有存档,则构建。这样设计的问题是,如他所述,当A中存储的向量变多之后,每次检查该向量是否之前被创建过的时间加长。

    这是一个典型的可以用映射表来解决的问题,把线性的复杂度转成常数的复杂度。他可以给每个向量设计一个独立无二的ID,比如直接转数字成id : num2str(vector)% 构建

    mydictionary = containers.Map

    % 插入数据

    id = num2str(vector) ; % 比如vector = [1 2 3];

    mydictionary('some_id') = vector ;

    之后的检索也是通过vector得到独一无二的ID,然后通过isKey来判断该键值是否已经被加入到MAP中去了。

    some_otherID = some_other_vector ;

    % 验证是否已经构建给过

    if mydictinary.isKey('some_otherID')

    % 做要做的工作

    end

    关于作者oopmatlab,计算物理博士,计算机硕士,声明:

    本文内容所有内容仅代表个人观点,如有任何问题,请联系作者。

    本版块所有文章版权归作者个人所有,未经允许,不得作为出版物出版。如需转载,请联系论坛管理员。

    展开全文
  • 高等非线性动力学-庞克来映射-相轨迹 弹簧质量系统在简谐激励作用下的受迫振动弹簧的恢复力F与变形x的关系为 3F0coswt 其中给定参数m=1c=0.3k=1.0F=kx动力学方程为mx+cx+kx=.3 w=1初始条件为x(0)=3.0x(0)=4.0设系统...
  • MATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在...

    MATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如containers.Map,tables,enumeration和time

    series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算使用。本篇首先介绍containers.Map数据类型。

    containers.Map简介

    MATLAB中最具代表性的高级数据类型是containers.Map,我们可以把它叫做映射表。它和函数映射有些类似,比如函数映射的定义是:

    F(x) = Y

    针对每一个X,都有一个唯一的Y与之对应,反之不一定。如图Fig.1所示。和函数映射相似,映射表用来形容键(Key)和键值(Key

    Value)之间的一一对应关系。每个Key都是独一无二的,且只能对一个Key

    Value。如图Fig.2所示。

    Fig.1

    函数映射关系

    Fig.2

    containers.Map类的映射示意图

    数组,元胞和结构体的局限性

    开始我们先介绍一下数组,元胞数组和结构体的局限性,为什么有的时候这些基本的数据类型无法满足程序的要求,换句话说,我们为什么需要containers.Map数据结构。假设要用MATLAB来记录电话号码簿中数据,比如表Table.1所示:

    Table.1 电话号码簿

    姓名

    电话号码

    Abby

    5086470001

    Bob

    5086470002

    Charlie

    5086470003

    先讨论数组,因为电话号码簿中既含有数字,又含有字符串,而数组中只能存放Double类型的数据,所以没有办法用数组直接记录电话号码薄中的内容。

    再试试元胞数组,我们在第1行预先声明一个3

    X 3的元胞数组,然后在2-4行按顺序填放号码簿的内容。

    % 元胞数组初始化

    addressBook

    = cell(3,1);

    % 预分配大小是MATLAB编程的好习惯

    addressBook{1}

    = {'Abby',

    '5086470001'};

    addressBook{2}

    = {'Bob'

    , '5086470002'};

    addressBook{3}

    = {'Charlie',

    '5086470003'};

    需要的时候,可以通过for循环访问其中的内容,比如:

    for iter

    = 1:length(addressBook)

    % 元胞数组的遍历

    addressBook{iter}

    % 通过Index访问元胞中的内容

    end

    但是按照顺序遍历电话号码簿没有什么实际用处,号码簿的主要功能应该是提供查找的功能才是。比如要想查询Charlie的电话号码,我们希望程序最好可以写成如下这样:

    CharlieNum

    = addressBook{'Charlie'}

    % 提示:这是错误的写法

    或者

    CharlieNum

    = addressBook.Charlie

    % 提示:这是错误的写法

    但是元胞数组的值只能通过Index去访问内容,不支持如上的访问方式。所以为了找到Charlie的电话号码,程序不得不遍历元胞中的所有内容,取出每一个元胞元素的第一列的字符串做比较,如果名字等于Charlie,则输出电话号码:

    % 使用for循环查找

    for iter

    = 1:length(addressBook)

    if strcmp(addressBook{iter}{1},'Charlie')

    addressBook{iter}{2}

    % 如找到则输出电话号码

    break;

    end

    end

    当然还有其他的方式来盛放电话号码簿,比如把电话和名字分别存到到两个元胞数组中去

    names

    = {'Abby','Bob','Charlie'};

    % 用元胞放号码

    numbers

    = {'5086470001','5086470002','5086470001'};

    % 用元胞放名字

    ind

    = find(strcmp(names,'Charlie'));

    % strcmp接受向量的输入 返回Logical数组

    % find紧接着找出逻辑数组中非零元素的Index

    numbers{ind}

    其中第3行strcmp接受元胞作为输入,在其中寻找Charlie,find函数将返回Charlie所在的位置,这样的方式比使用for循环要快,但无一例外的是,两种方法都要从头开始遍历一个数组,终究来说是慢的。

    除查找性能慢外,使用元胞盛放电话号码簿类型的数据还有其它缺点:

    无法方便的验证重复数据。电话号码簿要求每一个人的名字都是独一无二的,所以在数据录入的时候要防止姓名的重复,但是我们没有其它办法知道某名字是否已经被使用过了,除非在每次输入的时候都对整个元胞里的内容做遍历比较。

    无法方便地添加内容。如果电话号码簿中的记录需要不断地增长,但是我们没有办法在一开始就估计出其大概的数量,于是无法有效的预先分配内存,所以添加数据时,一旦超过预先分配的量,MATLAB就要重新分配内存了。

    无法方便地删除内容。如果我们要从元胞中去掉某一记录,可以找到该记录,并把该位置的元胞内容置空,但这并不会自动减小元胞数组的长度,如果

    这样的删减操作多了,元胞中会留下很多没有利用的空余位置。

    不方便作为函数的参数,具体原因见struct的局限性.

    最后我们再尝试一下用结构体盛放电话号码簿数据类型,struct的赋值很简单,比如可以直接赋值:

    % 赋值方法1

    addressBook.Abby

    = '5086470001';

    addressBook.Bob

    = '5086470002';

    addressBook.Charlie

    = '5086470003';

    或者:

    % 赋值方法2

    addressBook

    = struct('Abby','5086470001','Bob','5086470002','Charlie','5086470003')

    方法1和方法2是等价的。

    struct数据类型的查找很方便,比如要查询Charlie的电话号码,直接访问struct中的同名的field即可以了。

    num

    = addressBook.Charlie

    如果要查询的人名是一个变量,

    我们可以使用getfield函数:

    num

    = getfield(addressBook,name)

    % 其中name是变量

    struct盛放电话号码簿类型的数据,查询起来确实比元胞进步了不少,但还是有些不方便的地方。

    因为struct的field的名字要求必须是以字母开头,这是一个很大的局限,并不是所有的类似电话号码簿的结构都可以用人名做索引,比如账户号码簿,股票代码等等,他们通常是用数字开头的,比如图Table.2中的数据:

    Table.2 深证股票代码

    股票代码

    股票名称

    000001

    深发展

    000002

    万科

    000004

    ST国农

    如果我们要求通过股票的代码来查找股票的具体信息,struct无法简单的直接做到。

    使用struct的另一个不方便之处在于,当把struct当做函数参数,并且在函数内部需要对该struct做一定的修改时,为了要把修改后的结果返回,我们需要对原来的struct做完全的拷贝,显然如果struct中的数据很多的话,这样做是低效的。比如下面的函数中,addressBook被当做函数的参数传入,在函数中添加了一个新的field,

    为了返回更新后的结构,函数内部必须重新构造一个新的struct,也就是s返回给该函数的调用者。

    % 把struct当做函数的参数

    function s

    = modifystruct(s)

    s.Dave

    = '5086470004';

    end

    用containers.Map来记录电话号码簿

    上面一节我们介绍了数组,元胞数组和结构体在模拟电话号码簿这种数据结构时的局限性,这节我们来看怎么用containers.Map来盛放电话号码簿中的内容:

    addressMap

    = containers.Map;

    % 首先声明一个映射表对象变量

    addressMap('Abby')

    = '5086470001';

    addressMap('Bob')

    = '5086470002';

    addressMap('Charlie')

    = '5086470003';

    第一行我们声明一个containers.Map的变量(其实是containers.Map类的对象)叫做addressMap,2,3,4行通过提供Key

    Key Value的方式来给对象赋值,其中单引号内部的值叫做键(Key),等式右边的叫做键值(Key

    Value)。通过这个结构,我们在MATLAB内存中,建立起了如图Fig.3的映射关系数据结构。

    Fig.3

    电话号码簿映射表

    Fig.4

    Map类的UML

    查找addressMap对象中的内容极其方便,比如查找我们想知道Charlie的电话号码,只需:

    % 查找

    num

    = addressMap('Charlie')

    如果我们要修改Charlie的电话号码,只需

    % 赋值

    addressMap('Charlie')

    = newNum;

    什么是containers.Map

    containers.Map是一个MATLAB的内置类(类是面向对象编程中的一个基本概念,在这里可以把类暂时理解成一种数据类型),所谓内置,就是MATLAB内部实现的,通常这种类的性能更加的优秀。containers.Map其中containers是Package的名称,Map是该Package中的一个类,Map是它的类名。用UML(Unified

    Modeling Language)的语法把该类表示出来,它的属性包括Count,

    KeyType,ValueType。它的常用方法包括keys,values,isKey,remove。如图Fig.4所示。

    containers.Map的属性和成员方法

    这节我们介绍containers.Map的属性和成员方法,假设我们这样初始化一个containers.Map对象:

    % 初始化一个Map对象

    addressMap

    = containers.Map;

    addressMap('Abby')

    = '5086470001';

    addressMap('Bob')

    = '5086470002';

    addressMap('Charlie')

    = '5086470003';

    在命令行中键入该对象的名称,MATLAB会显示该对象属性的基本信息:

    >>

    addressMap

    addressMap

    =

    Map

    with

    properties:

    Count:

    3 % MAP 中映射对的数目

    KeyType:

    char % MAP 中键的类型

    ValueType:

    any

    % MAP 中键值的类型

    其中Count

    表示Map对象中映射对的数目。按照规定,键的类型一定要是字符类型,不能是其它数据类型,而键值的类型可以是MATLAB中的任意类型:数组,元胞,结构体,MATLAB对象,甚至JAVA对象等等。因为键值的类型可以是任何MATLAB类型,所以containers.Map是MATLAB中极其灵活的数据类型。

    成员方法keys 用来返回对象中所有的键:

    >>

    addressMap.keys

    ans

    =

    'Charlie' 'Abby' 'Bob'

    成员方法values用来返回对象中的所有键值

    >>

    addressMap.values

    ans

    =

    '5086470003' '5086470001' '5086470002'

    remove用来移除对象中的一个键-键值对,经过下面的操作之后,该对象中的Count的值变成了2。

    >>

    addressMap.remove('Charlie')

    ans

    =

    Map

    with

    properties:

    Count:

    2 % 映射对数目减少

    KeyType:

    char

    ValueType:

    any

    isKey成员方法用来判断一个map对象中是否已经含有一个键值,比如:

    >>

    addressMap.isKey('Abby')

    ans

    =

    1

    >>

    addressMap.isKey('abby')

    % 键是大小写敏感的

    ans

    =

    0

    isKey的功能是查询,类似之前提到的find和strcmp函数合起来使用的例子。

    containers.Map的特点

    containers.Map可以不断地扩张不需预分配

    使用数组和元胞数组作为数据容器,通常要预先分配容器的大小。否则每次扩充容器,MATLAB都会重新分配内存,并且拷贝原来数组中的数据到新分配的内存中去。映射表是一个可以灵活扩充的容器,并且不需要预分配,每次往里面添加内容不会引起MATLAB重新分配内存。

    我们可以通过提供两个元胞来构造映射表对象,比如下面我们构造一个机票簿数据结构:

    % 映射表的初始化方法1

    ticketMap

    = containers.Map(

    {'2R175',

    'B7398',

    'A479GY'},

    ...

    {'Abby',

    'Bob, 'Charlie'});

    也可以在程序的一开始,先声明一个对象:

    % 映射表的初始化方法2

    >>

    ticketMap

    = containers.Map

    然后在计算的过程中慢慢的向表中插入数据:

    % 映射表的初始化方法2

    >>

    ticketMap['2R175']

    = 'Abby';

    ...

    >>

    ticketMap['A479GY']

    = 'Charlie;

    containers.Map可以作为参数在函数内部直接修改

    因为containers.Map是handle类(handle类的介绍参见《MATLAB面向对象编程-从入门到设计模式》第三章:MATLAB的句柄类和实值类),我们还可以方便的将这个对象传给任何MATLAB的函数,并且在函数内部直接修改对象内部的数据,并且不用把它当做返回值输出,比如:

    >>

    modifyMap(ticketMap);

    modifyMap函数可以写成:

    function modifyMap(ticketMap)

    % 该函数没有返回值

    .....

    ticketMap(NewKey)

    = newID

    end

    注意这里没有把修改的ticketMap当做返回值,在函数中我们直接修改了Map中的数据,这是MATLAB面向对象语言中handle类的特性。

    containers.Map可以增强程序的可读性

    映射表内部可以存储各种类型的数据,并且给它们起一些有意义的名字。具体的例子见元素周期表的例子。

    访问和修改这些数据的时候,可以直接使用这些有意义的名字,从而增加程序的可读性。而如果用元胞数组存储这些数据,在访问和修改这些数据的时候,

    需要使用整数的Index,程序可读性不够好。

    containers.Map提供对数据的快速查找

    映射表查找的复杂度是常数O(C)的,而传统的数组和元胞数组查找的复杂度是线性O(N)的。如果不熟悉算法中复杂度的概念,可以这样理解:如果使用数组或者元胞来存储数据,当我们要在该数据结构中搜索一个值时,只能做线性搜索,平均下来,搜索的时间和该数据结构中的元素的数目N成正比,即元胞和数组中的元素越多,找到一个值所用的时间就越长,这叫做线性的复杂度

    O(N)。而映射表采取的底层实现是哈希表(Hash

    Map),搜索时间是常数C,理论上来说搜索速度和集合中元素的个数没有关系。所以当容器中元素数量众多的时候,要想查找得快,可以使用containers.Map结构。具体例子见快速查找的例子。

    下面通过对假想的数据集合进行查找,来比较一下数组和container.Map的性能。我们第一行先构造一个含有1000000(10^7)个整数的数组(这是数组中元素的个数很多,如果只有少量元素,线性查找的效率会高一些),按顺序填充从1到(10^7)的整数;作为比较,第二行再构造一个containers.Map对象,往内部填充从1到(10^7)的整数,Key和KeyValue都相同。

    a

    = 1:1000000;

    m

    = containers.Map(1:1000000,ones(1,1000000));

    数组数据结构,使用find函数依次查找从1到(10^7)的整数,在笔者的机器上,耗时28.331901秒

    % array的查找

    tic

    for i=1:100000,

    find(b==i);

    end;

    toc

    % command line结果

    Elapsed

    time

    is

    28.331901 seconds.

    containers.Map数据结构,使用键值1到(10^7)进行访问,

    在笔者的机器上,耗时只需1.323007秒,

    结论是:如果有大量的数据,并且要频繁的进行查找操作,可以考虑使用containers.Map数据结构。(读者可以试试减少容器中元素的个数,观察一下什么情况下,数组的查找会更快一些。)

    % 映射表的查找

    tic

    for i=1:100000,

    m(i);

    end;

    toc

    % command line结果

    Elapsed time is 1.323007 seconds.

    谈到在MATLAB中使用高级数据结构,另一种常见的做法是直接使用Java和Python对象,这里顺便比较一下在MATLAB中使用Java的哈希表的效率。再笔者的机器上,耗时3.072889秒.

    % JAVA哈希表的查找

    s

    = java.util.HashSet();

    for i=1:100000,

    s.add(i);

    end

    tic;

    for i=1:100000,

    s.contains(i);

    end;

    toc

    % command line结果

    Elapsed

    time

    is

    3.072889 seconds.

    containers.Map的使用实例

    用来盛放元素周期表

    工程计算中可以使用这种键-键值的例子有很多。比如物理化学计算中可以用映射表来盛放元素周期表中的内容:

    >>

    ptable

    = containers.Map;

    >>

    ptable('H')

    = 1 ;

    >>

    ptable('He')

    = 2 ;

    其中键是原子符号,而键值是原子量。因为键值的类型不限,所以键值本身还可以是对象,比如Atom类对象,其中包涵更多有用的内容:

    % 类文件Atom.m

    classdef Atom

    < handle

    properties

    atomicNumber

    fullName

    end

    methods

    function obj

    = Atom(num,name)

    obj.atomicNumber

    = num

    ;

    obj.fullName

    = name

    end

    end

    end

    \end{Verbatim}

    于是:

    % 键值可以是Atom对象

    >>

    ptable('H')

    = Atom(1,'hydrogen');

    >>

    ptable('H')

    = Atom(2,'helium');

    用来实现快速地检索

    这个问题来自ilovematlab一个网友的提问:

    大家好,最近遇到一个问题,要构建20000次以上的三元素向量,且保证每次不重复构建,该向量元素值在2000―3000之间不定数,目前采用的方法是建立一历史档案矩阵A,构建一个存储一行,A大小行数持续增加。每次在构建出一新的向量时对该向量与历史档案矩阵每行进行对比,最终确定是否构建过,若没构建过,重新构建。算法显示该检查程序运算时间在执行20000次以上时,会超过200S的运行时间。想力争减小该时间,求方法。

    多谢!

    这位网友的问题不在于如何构建这些向量,而是如何保证每次不重复的构建。他一开始想出的解决方法是用矩阵A来存储历史档案,每建立一个新的向量,和该历史档案已有的内容做比较,如果在档案中没有存档,则构建。这样设计的问题是,如他所述,当A中存储的向量变多之后,每次检查该向量是否之前被创建过的时间加长。

    这是一个典型的可以用映射表来解决的问题,把线性的复杂度转成常数的复杂度。他可以给每个向量设计一个独立无二的ID,比如直接转数字成id

    :num2str(vector)

    % 构建

    mydictionary

    = containers.Map

    % 插入数据

    id

    = num2str(vector)

    ; % 比如vector = [1 2 3];

    mydictionary('some_id')

    = vector

    ;

    之后的检索也是通过vector得到独一无二的ID,然后通过isKey来判断该键值是否已经被加入到MAP中去了。

    some_otherID

    = some_other_vector

    ;

    % 验证是否已经构建给过

    if mydictinary.isKey('some_otherID')

    % 做要做的工作

    end

    展开全文
  • logistic regression属于概率型非线性回归,它是研究二分类观察结果与一些影响因素之间关系的一种多变量分析方法。例如,在流行病学研究中,经常需要分析疾病与各危险因素之间的定量关系,为了正确说明这种关系,...

    logistic regression属于概率型非线性回归,它是研究二分类观察结果与一些影响因素之间关系的一种多变量分析方法。例如,在流行病学研究中,经常需要分析疾病与各危险因素之间的定量关系,为了正确说明这种关系,需要排除一些混杂因素的影响。对于线性回归分析,由于应变量Y是一个二值变量(通常取值1或0),不满足应用条件,尤其当各因素都处于低水平或高水平时,预测值Y值可能超出0~1范围,出现不合理都现象。用logistic回归分析则可以较好的解决上述问题。Logistic回归模型的基本形式如下:

    705e0091b68ad2dc995a7245a3d4dbba.png

    因此,对因变量P按照ln(P/(1-P))的形式进行对数变换,可以将Logistic回归问题转化为线性回归问题,在按照多元线性回归的方法求解回归参数。对于P取值只有0和1的情况,在实际中不是直接对P进行回归,而是先定义一个单调连续的概率函数π:

    fa92b799527ed7f25e8ef37a6eed7850.png

    此时Logistic模型为:

    22078d7b3a9d1a226cd48e7ab11dc3fa.png

    然后只需要对原始数据进行合理的映射处理,就可以用线性回归方法得到回归系数,最后再根据π和P的映射关系进行反映射得到P的值。
    下面是书中的一个例子,评估企业的还款能力,已知前20家企业的评价指标和评价结果,要求对剩余5家企业进行评估。数据如下:

    e267466fe3d4b77c01cc39b9be760656.png

    Π到P的映射关系:

    62eaf5ecbbf8c95d69c6d1165000f5ae.png

    Π值的确定:

    dd8d78685b943be060900b178d2a5532.png

    Matlab代码如下:

    1. clear all
    2. clc
    3. %数据格式
    4. format long
    5. %前20组数据
    6. X0=xlsread('D:资料库区大三上HUAWEIMATLAB11Logistic.xls','E4:G23');
    7. %全部25组数据:验证和回归
    8. XE=xlsread('D:资料库区大三上HUAWEIMATLAB11Logistic.xls','E4:G28');
    9. %前20组评估的数据值:P
    10. Y0=xlsread('D:资料库区大三上HUAWEIMATLAB11Logistic.xls','H4:H23');
    11. n=size(Y0,1);
    12. %π和P的映射关系
    13. for i=1:n
    14. if Y0(i)==0
    15. Y1(i,1)=0.25;
    16. else
    17. Y1(i,1)=0.75;
    18. end
    19. end
    20. %构建常系数
    21. X1=ones(size(X0,1),1);
    22. X=[X1,X0];
    23. Y=log(Y1./(1-Y1));
    24. b=regress(Y,X);
    25. %模型验证的应用
    26. for i=1:size(XE,1)
    27. pai0=exp(b(1)+b(2)*XE(i,1)+b(3)*XE(i,2)+b(4)*XE(i,3))/(1+exp(b(1)+b(2)*XE(i,1)+b(3)*XE(i,2)+b(4)*XE(i,3)));
    28. if(pai0<=0.5)
    29. P(i)=0;
    30. else
    31. P(i)=1;
    32. end
    33. end
    34. %回归结果
    35. disp(['回归系数:' num2str(b') ' ']);
    36. disp(['评估结果:' num2str(P) ' ']);

    Matlab运行结果如下:

    c51612ffe469743774e32a12121cb695.png

    第一行即为该问题中回归模型的系数,带入即可得到回归模型,第二行为该模型的评估结果。

    展开全文
  • 补给箱陈泽光:复分析学习笔记 - 共形映射​zhuanlan.zhihu.com领取补给后开启今天的内容前情提要我们在 复分析学习笔记 - 共形映射 中提及,共形映射具有保角性和伸缩率不变性. 而本章涉及的分式线性变换( 变换)...
  • 2matlab习题及结果解析第1章 MATLAB概论与其他计算机语言相比较,MATLAB语言突出的特点是什么?MATLAB具有功能强大、使用方便、输入简捷、库函数丰富、开放性强等特点。1.2 MATLAB系统由那些部分组成?MATLAB系统...
  • 在由线性方程组发展出来的理论体系中, 有一个概念始终占据着核心地位, 那就是线性空间(或线性性)的概念. 很多学生都觉得代数比较难, 主要是觉得代数太抽象. 其实数学发展的一般规律是: 从特殊到一般, 从具体到抽象,...
  • 本文收集了我对李尚志教授的《线性代数》书中习题给出的解答。有兴趣的知友可在评论区对内容提出意见。第二章 第六节习题4设 是所有的正实数组成的集合。对任意 定义 (实数 按通常乘法的乘积),对任意 和 定义 。...
  • 奈奎斯特稳定性判据 奈奎斯特稳定性判据是研究线性系统(齐次性、叠加性)相对稳定的基本方法,它的理论基础是复变函数中柯西(Cauchy)定理。 3. 围线映射 在频域稳定性中关心的是由函数 F(s) 诱导的围线映射,它...
  •   对于(看作几何空间)而言,一张不过原点的平面是不能成为一个线性空间的,因为这个平面上两个向量的差:并不位于上,但如果另有一个与其平行的平面过原点:则便是一个线性子空间,且位于中。  一个想法是:考察...
  • 补给箱陈泽光:复分析学习笔记 - 共形映射​zhuanlan.zhihu.com陈泽光:复分析学习笔记 - 分式线性变换​zhuanlan.zhihu.com领取补给后开启今天的内容我们曾在 复分析学习笔记 - 分式线性变换 中提及,分式线性变换...
  • 基于Matlab解决m个人\n项任务的最优分派[摘要]对图论中二元匹配问题及其不同要求下的最优匹配问题,在线性规划的理论基础上,基于Matlab软件,给出最大效益或最小成本的求解程序及运行命令。具有较广泛和很方便的实际...
  • matlab中,每个figure都有(而且仅有)一个colormap,翻译过来就是色图。 COLORMAP(MAP) 用MAP矩阵映射当前图形的色图。 COLORMAP('default') 默认的设置是 JET. MAP = COLORMAP 获得当前色图矩阵. COLORMAP(AX,...)...
  • 我们关注的是Taylor展开的线性部分,这部分的线性系数就是函数的导数。在多元函数中,这部分的一组线性系数构成了某种线性组合。站在线性代数的角度看待Taylor展开的线性部分,我们考虑两个问题:坐标的微分能否构成...
  • 这个由于计算较为繁琐,我们可以交给MATLAB完成,使用eig命令既可以计算特征值,也可以计算特征向量。 当最大特征值等于矩阵阶数的时候,我们的正互反矩阵才为一致矩阵: 当最大特征值与n相差越大时,我们得到的...
  • 经过几番考虑之后,他动笔计算 与 的复合,整理得到一个新的线性映射: 凯莱默想着这个方程式,或许是从行列式得来的灵感,他突然想到为何不用阵列来表示线性映射的系数呢?于是他将线性映射 , 和 分别表示为 像...
  • 当然这并不是唯一的选择,其中Matlab也是一种高效的实现工具。 第一节 线性回归 线性回归(Linear Regression) 即假设样本数据呈现线性关系,用线性模型基于最小均方误差MSE的准则,找出一条最佳分类决策边界。 ...
  • 高等非线性动力学-庞克来映射-相轨迹 弹簧质量系统在简谐激励作用下的受迫振动弹簧的恢复力F 与变形x 的关系为 . . 3 m x+c x+kx3 F cos wt c 0.3 k 1.0 F=kx 动力学方程为 其中给定参数 0 m 1 . w 1 初始条件为x (0...
  • 利用BP网络实现非线性函数映射(基于matlab工具箱) 目录利用BP网络实现非线性函数映射(基于matlab工具箱)一、网络结构二、学习过程三、学习结果四、误差分析五、实验总结附录(源程序) 实验目的:自己设计一个BP...
  • HDR 色调映射线性压缩(matlab) 目录 HDR 色调映射学习(matlab) 1、介绍 2、matlab在HDR上的应用 参考文章: 1、介绍 即使在引入数码相机之后,多年来,专业摄影师还是更喜欢使用基于胶片的SLR相机进行...
  • 定义式: 实现: function y=PWLCM(x,p) if x<p y=x/p; elseif x<0.5 y=(x-p)/(0.5-p); else y=PWLCM(1-x,p); end end

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 254
精华内容 101
关键字:

matlab线性映射

matlab 订阅