前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原 初学数模-MATLAB Quick S

原 初学数模-MATLAB Quick S

作者头像
不高不富不帅的陈政_
发布2018-05-18 15:47:48
1.6K0
发布2018-05-18 15:47:48
举报
文章被收录于专栏:聊聊技术

    其实,这个矩阵被叫做Magic Square,是因为他的每行每列、主对角线和副对角线数字之和全部相等,且都是(1+16)*2=34。

    (话说微博网红、艺术科普作家、广告狗顾爷还曾花了很大篇幅在《小顾聊绘画》里介绍丢勒大师,有兴趣的童鞋可以去翻翻,个人感觉挺好看的)

    那我们就把它输入到MATLAB里吧~

代码语言:javascript
复制
A = [16 3 2 13; 5 10 11 8; 9 6 7 12; 4 15 14 1]

    Hint:试一试第一章介绍的其他的输入方式!

    现在,你已经能在工作区(workspace)看到它了,此时我们可以直接用变量名A代指它。

现在我们来介绍几个MATLAB基本函数:

1.求和函数sum:对矩阵的每列求和,如sum(A)的运行结果为:

代码语言:javascript
复制
ans=
    34 34 34 34

          现在ans已经是一个一行四列的向量了。

          如果不指定输出值保存在哪个变量中,MATLAB就会把结果暂时保存在ans变量中。

          Q:想一想有几种方法求矩阵A每行之和呢?

          Hint:查阅一下官方文档对sum函数的介绍,命令为:doc sum

2.转置矩阵A':返回矩阵A的转置矩阵,如A'的运行结果为:

代码语言:javascript
复制
ans =
    16 5 9 4
    3 10 6 15
    2 11 7 14
    13 8 12 1

        Hint:在命令行中试一试B=A'这条命令!

3.翻转函数fliplr:将矩阵的第一列与最后一列交换、第二列与倒数第二列交换……篇幅所限,这里就不再演示fliplr(A)了~

4.对角阵diag:取主对角线元素,作为一个向量。

        Hint:试一试sum(diag(fliplr(A')))!

5.生成幻方的magic函数:如B = magic(4),MATLAB就会返回给你一个满足条件的幻方:

代码语言:javascript
复制
B =
    16 2 3 13
    5 11 10 8
    9 7 6 12
    4 14 15 1

        Hint:现在矩阵B与矩阵A都满足幻方(magic square)的性质,那么这两个矩阵有什么不同?

    在MATLAB中,你可以通过三种方法来获得一个矩阵:

            1.手动输入

            2.在mat文件中读取

            3.通过MATLAB函数(除了自带的函数,你还可以自己定义一些函数!)生成

    其中,最常用的就是第一种和第三种了。

    而MATLAB也有许多有用的矩阵构造函数,如:zeros、ones、rand、randn、perms等。

    Hint:记得查阅下find函数的官方资料。

变量名:话说MATLAB的变量名会区分大小写,且变量名长度不应大于63个字符(肯定够用啦)。

代码语言:javascript
复制
>>N = namelengthmax
>>N = 
    63

数字:MATLAB支持科学计数法和复数的输入(i 和 j 都是虚数单位),而以下数字都是合法的:

代码语言:javascript
复制
3          -99          0.0001
9.6397238  1.60210e-20  6.02252e23
1i         -3.14159j    3e5i

    有时,数字的存储方式不当也会造成一些溢出错误,如:

MATLAB stores all numbers internally using the long format specified by the IEEE® floating-point standard. Floating-point numbers have a finite precision of roughly 16 significant decimal digits and a finite range of roughly 10-308 to 10+308. Numbers represented in the double format have a maximum precision of 52 bits. Any double requiring more bits than 52 loses some precision. For example, the following code shows two unequal values to be equal because they are both truncated: x = 36028797018963968; y = 36028797018963972; x == y ans = 1 Integers have available precisions of 8-bit, 16-bit, 32-bit, and 64-bit. Storing the same numbers as 64-bit integers preserves precision: x = uint64(36028797018963968); y = uint64(36028797018963972); x == y ans = 0

    这里,x==y表示“x与y是否相等”。如相等则返回1,否则返回0。

    这里再介绍一下MATLAB中的内置排序函数sort: MATLAB把一切数字都当做复数处理,因此每个数字都有其相位角(即与x轴的夹角)。而sort函数则按照“先模长,后相位”的优先级进行排序,如:

代码语言:javascript
复制
>> sort([3+4i, 4+3i,6+8i,5,6])

ans =

  Columns 1 through 4

   5.0000 + 0.0000i   4.0000 + 3.0000i   3.0000 + 4.0000i   6.0000 + 0.0000i

  Column 5

   6.0000 + 8.0000i

    你可以通过angle函数查询相位角:

代码语言:javascript
复制
>> angle(3+4i)

ans =

    0.9273

    当然,这是以弧度制储存的。

    关于矩阵的基本运算,笔者在MATLAB Quick Start的第一篇就写过了,详情请见这里☞http://my.oschina.net/bgbfbsdchenzheng/blog/501141

    在构造矩阵时,这些运算特别方便,如:

代码语言:javascript
复制
>> n = (0:9)';
>> pows = [n n.^2 2.^n]

pows =

     0     0     1
     1     1     2
     2     4     4
     3     9     8
     4    16    16
     5    25    32
     6    36    64
     7    49   128
     8    64   256
     9    81   512

函数:在MATLAB库中,函数何止千千万。笔者自然也不能逐个介绍。但是官方文档则介绍的相当详细:

For a list of the elementary mathematical functions, type help elfun   %You will see you are familiar with some of them, such as sin,cos,exp.... For a list of more advanced mathematical and matrix functions, type help specfun help elmat Some of the functions, like sqrt and sin, are built in. Built-in functions are part of the MATLAB core so they are very efficient, but the computational details are not readily accessible. Other functions are implemented in the MATLAB programing language, so their computational details are accessible. There are some differences between built-in functions and other functions. For example, for built-in functions, you cannot see the code. For other functions, you can see the code and even modify it if you want.

    如果你让一个非零值除以0,或者得到数值大于matlab允许的最大值(大约为10^308),MATLAB很可能会返回给你一个Inf。而一些无法用数学方法表达的数字,如 Inf-Inf 或者 0/0,则是NaN。

    但是,你甚至可以暂时的改变这些常量

代码语言:javascript
复制
>> pi = 4

pi =

     4   %此时pi是一个临时变量

>> clear pi    %清除对pi的改变
>> pi

ans =

    3.1416

    有时候,我们需要MATLAB按照特定格式显示数字。那么,如何在MATLAB中改变数字格式呢?

    很简单,使用 format 命令就好了。

代码语言:javascript
复制
x = [4/3 1.2345e-6]

format short   %最简单的short型
    1.3333 0.0000

format short e    %科学计数法,显示的有效位数与short相同
    1.3333e+000 1.2345e-006

format short g    %优先使用short,必要时使用科学计数法
    1.3333 1.2345e-006

format long    %long型,输出更多位数
    1.33333333333333 0.00000123450000

format long e    %%科学计数法,显示的有效位数与long相同
    1.333333333333333e+000 1.234500000000000e-006

format long g    %优先使用long,必要时使用科学计数法
    1.33333333333333 1.2345e-006

format bank    %保留两位小数
    1.33 0.00

format rat    %化为最接近的分数
    4/3 1/810045

format hex    %十六进制输出
    3ff5555555555555 3eb4b6231abfd271

    Hint:如果你觉得这些格式还不够用,那么你甚至可以用fprintf和sprintf函数来自定义格式!

    说了这么多了,那么如何进行一整行的删除操作呢?其实很简单,把它赋值为空即可!

代码语言:javascript
复制
A(2,:) = []   %删除第二行
A(:,3) = []   %删除第二列

    还可以这样玩:

代码语言:javascript
复制
A(1:2,2:3) = 0    %分别将第一、二行的第二、三列元素置为0

    逻辑操作:我们可以对特定的元素操作,即使现在不知道它们的下标,而只需要满足一定逻辑条件(如“是实数”、“是素数”等)即可。

    现在有这样一个向量:

代码语言:javascript
复制
x = [2.1 1.7 1.6 1.5 NaN 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8];

    我们如果想去掉NaN,再把“离群”的5.1去掉,就可以这样操作:

代码语言:javascript
复制
x = x(isfinite(x))   
x =
    2.1 1.7 1.6 1.5 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8

x = x(abs(x-mean(x)) <= 3*std(x))    %std(x)表示x的标准差
x =
    2.1 1.7 1.6 1.5 1.9 1.8 1.5 1.8 1.4 2.2 1.6 1.8

Find函数:非常的简单,如把A中的素数元素替换为NaN,就可以这样操作:

代码语言:javascript
复制
>> A = magic(4)

A =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

>> isprime(A)

ans =

     0     1     1     1
     1     1     0     0
     0     1     0     0
     0     0     0     0

>> find(isprime(A))'

ans =

     2     5     6     7     9    13
 
>> A(k) = NaN

A =

    16   NaN   NaN   NaN
   NaN   NaN    10     8
     9   NaN     6    12
     4    14    15     1

    现在,我们就可以自己生成“幻方”(Magic Square)了~

代码语言:javascript
复制
p = perms(1:4);   %生成4!=24个1-4的组合序列,如(1 2 3 4、 2 3 4 1)等
A = magic(4);    
M = zeros(4,4,24);
for k = 1:24
    M(:,:,k) = A(:,p(k,:));
end

%此时M就是24个4*4的幻方的“结合体”了,是一个三维的数组。现在我们来查看一下M的大小:
>>size(M)
ans = 
    4 4 24

    最后,是元胞数组与结构体

    元胞数组(Cell Array)是个筐,什么都能往里装→_→ 只是定义时记得用大括号{}就好了

代码语言:javascript
复制
>>C = {A sum(A) prod(prod(A))}    %A是magic square,prod函数即produce of,用于求连乘
C =
    [4x4 double] [1x4 double] [20922789888000]

    还可以用cell来定义一个元胞数组,如下:

代码语言:javascript
复制
M = cell(8,1);    %定义一个8行1列的元胞数组
for n = 1:8
    M{n} = magic(n);
end
M

M =
    [ 1]
    [ 2x2 double]
    [ 3x3 double]
    [ 4x4 double]
    [ 5x5 double]
    [ 6x6 double]
    [ 7x7 double]
    [ 8x8 double]

    要想从中选取第四个“元胞”,只需要输入M{4}即可:

代码语言:javascript
复制
>> M{4}

ans =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

    下面来说说初级结构体操作:

在MATLAB中,甚至不需要定义一个结构体,直接对它赋值即可

代码语言:javascript
复制
S.name = 'Ed Plum';
S.score = 83;
S.grade = 'B+'

%查看现在的S
>>S
S = 

     name: 'Ed Plum'
    score: 83
    grade: 'B+'

    再来定义个:

代码语言:javascript
复制
S(2).name = 'Toni Miller';
S(2).score = 91;
S(2).grade = 'A-';

S(3) = struct('name','Jerry Garcia',...
'score',70,'grade','C')

%现在这个结构体数组已经太大了,因此不会在屏幕上直接显示
S = 

1x3 struct array with fields:

    name
    score
    grade

    现在我们想要S中的所有grade:

代码语言:javascript
复制
>> S.grade    %与S(1).score, S(2).score, S(3).score相同

ans =

    B+


ans =

    A-


ans =

    C

    我们再来对score做做文章:

代码语言:javascript
复制
>>scores = [S.score]    %把S中的score全部提取到scores中
scores =
    83 91 70
    
>>avg_score = sum(scores)/length(scores)
avg_score =
    81.3333

    name元素也一样

代码语言:javascript
复制
>>names = char(S.name)
names =
    Ed Plum
    Toni Miller
    Jerry Garcia
    
>>names = {S.name}
names =
    'Ed Plum' 'Toni Miller' 'Jerry Garcia'
    
>>[N1 N2 N3] = S.name
N1 =
    Ed Plum
N2 =
    Toni Miller
N3 =
    Jerry Garcia

    好啦,今天就到这里。话说最近的竞赛一个接一个,上周末因为大学生数模一直没更,这周的周末又是ACM北京区域赛的网赛,下周周末又是合肥区域赛的网赛,所以估计又要几天不更了,恩就是这样。。= =

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档