原 初学数模-MATLAB Quick S

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

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

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

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)的运行结果为:

ans=
    34 34 34 34

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

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

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

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

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

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就会返回给你一个满足条件的幻方:

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个字符(肯定够用啦)。

>>N = namelengthmax
>>N = 
    63

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

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函数则按照“先模长,后相位”的优先级进行排序,如:

>> 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函数查询相位角:

>> angle(3+4i)

ans =

    0.9273

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

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

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

>> 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。

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

>> pi = 4

pi =

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

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

ans =

    3.1416

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

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

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函数来自定义格式!

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

A(2,:) = []   %删除第二行
A(:,3) = []   %删除第二列

    还可以这样玩:

A(1:2,2:3) = 0    %分别将第一、二行的第二、三列元素置为0

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

    现在有这样一个向量:

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去掉,就可以这样操作:

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,就可以这样操作:

>> 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)了~

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)是个筐,什么都能往里装→_→ 只是定义时记得用大括号{}就好了

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

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

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}即可:

>> M{4}

ans =

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

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

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

S.name = 'Ed Plum';
S.score = 83;
S.grade = 'B+'

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

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

    再来定义个:

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:

>> S.grade    %与S(1).score, S(2).score, S(3).score相同

ans =

    B+


ans =

    A-


ans =

    C

    我们再来对score做做文章:

>>scores = [S.score]    %把S中的score全部提取到scores中
scores =
    83 91 70
    
>>avg_score = sum(scores)/length(scores)
avg_score =
    81.3333

    name元素也一样

>>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北京区域赛的网赛,下周周末又是合肥区域赛的网赛,所以估计又要几天不更了,恩就是这样。。= =

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阿凯的Excel

巧妙解决二维表信息匹配问题

15320
来自专栏CDA数据分析师

用SPSS做数据分析?先弄懂SPSS的基础知识吧

1、SPSS数据分析的流程 ? 2、SPSS特性: ? 3、数据的编辑: 1 常量 数值型常量:除了普通写法外还可以用科学计数法,如:1.3E18; 字符型常量...

413100
来自专栏杨建荣的学习笔记

使用贪心算法解决集合覆盖问题

有的同学可能对这些州没概念,这个简称就跟京代表北京,鲁代表山东,甘代表甘肃一样,细细一看,都是西部的一些州。

14220
来自专栏人工智能LeadAI

讨厌算法的程序员 2 | 证明算法的正确性

第1篇介绍了插入排序算法,这里要提出一个问题:学习算法仅仅是积累一个又一个的算法实现吗? 当然不是。比算法本身更重要也更基础的,是对算法的分析:能够证明其正确性...

36650
来自专栏程序员叨叨叨

6.5 Swizzle 操作符

可以使用Cg语言中的swizzle操作符(.)将一个向量的成员取出组成一个新的向量。swizzle操作符被GPU硬件高效支持。swizzle操作符后接x、y、z...

23150
来自专栏CDA数据分析师

提升R代码运算效率的11个实用方法

众所周知,当我们利用R语言处理大型数据集时,for循环语句的运算效率非常低。有许多种方法可以提升你的代码运算效率,但或许你更想了解运算效率能得到多大的提升。本文...

22480
来自专栏数据结构与算法

UOJ#386. 【UNR #3】鸽子固定器(链表)

如果我们按$s$排序后,我们就可以枚举$max  \ s_i$和$min \ s_i$

11310
来自专栏chenjx85的技术专栏

leetcode-453-Minimum Moves to Equal Array Elements

32860
来自专栏程序员宝库

用 PHP 的方式实现的各类算法合集

项目地址: https://github.com/PuShaoWei/arithmetic-php About 如果说各种编程语言是程序员的招式,那么数据结构和...

45870
来自专栏zaking's

js算法初窥07(算法复杂度)

13630

扫码关注云+社区

领取腾讯云代金券