初学数模-MATLAB Quick Start! Part II

让我们先从一张图片说起:

这幅画是由德国大画家丢勒(Albrecht Dürer)所画,其中布满了数学符号。在右上方的窗户上,你会发现那是一个矩阵。我们就从这里开始。

那么,在这幅名画中出现的矩阵究竟有何神通呢?

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

时间: 2024-10-19 04:42:30

初学数模-MATLAB Quick Start! Part II的相关文章

初学数模-MATLAB Quick Start! Part I

MATLAB这个语言灰常牛B大家都知道,封装性良好且支持混合编程.比如... OK,现在我们打开MATLAB Hint: 官方帮助文档很给力! 在MATLAB程序中,由于矩阵运算的重要,我们可以理解为"一切变量皆向量". 学习语言时,许多时候我们都从Hello World开始,在MATLAB中,这一个程序是这样的: disp('Hello World!'); 恩,确实只需要一行... 按你胃(Anyway),我们还可以给一个变量赋值 a = 2 还可以让给一个变量赋值为向量 a = [

数模讲座笔记

数模讲座笔记 概述 97%的参赛队是中国人 奖项分为O奖,F奖,M奖(一等奖),H奖(二等奖),S奖(成功参赛奖) 评审 初审:只有两个评委,审阅时间很快,10min左右 初审对所有的队伍进行打分,会刷掉近一半的队伍,刷掉的队伍一般获S奖 终审:分三轮 一二轮:决定前20名进入第三轮,剩下的按排名获M奖,H奖 三轮:直接决定O奖或F奖,评奖很主观,详见PPT 论文技巧 资料搜索时 搜索相关文献,大数据相关题目可用爬虫之类的工具 文献综述 了解问题的背景:连续题?离散题?大数据?网络流?环境相关?

数模常用算法系列--整数线性规划(分枝定界法)、整数非线性规划(蒙特卡洛法)

整数线性规划求解----分枝定界法 什么是整数规划? ? 线性规划中的变量(部分或全部)限制为整数时,称为整数规划.若在线性规划模型中,变量限制为整数,则称为整数线性规划.目前所流行的求解整数规划的方法,往往只适用于整数线性规划.目前还没有一种方法能有效地求解一切整数规划. 整数规划的分类 - 变量全限制为整数时,称(完全)整数规划 - 变量部分限制为整数时,称混合整数规划 什么是分枝定界法 ? 原理如下: ? 设有最大化的整数规划问题A,与它相应的线性规划为问题B,从解问题B开始,若其最优解不

2019数模国赛总结

先说重点:我们组选择的是B题,第一问优化掉空气阻力,并且忘记给出最优决策下的高度(真的是遗憾,我们居然忘了这个),第三问给出思路和总的方程,未给定解的表达.第四问是给定了力,然后给出两种策略来考虑可行性.由于时间没有把握好,论文主体写成了,但是存在一些表述上的瑕疵. ? 如果看了这些话,你还对这篇博客感兴趣,那我们就继续. ? 选题:C→A→B→A→B→A.... ? 晚上题发下来,讨论一会儿,感觉A,B都有坑,就C还比较友好,问题是坑爹的,C没数据(知乎热搜,选C题的都在搜数据hhh...),

数模三天乐

我们学校有个很不错的历史传统,就是五一三天假会有一个大型的娱乐项目,"数模三天乐",简直把人爽得不行不行的.一般地说是"自愿报名",但是苦逼的数学系出身还有各种各样的原因吧,最终还是不得不报名打一把数模. 数模和ACM是两个完全不同的竞赛.从过程上和准备上讲,数模对于大家来说都是三天决定结果,但是ACM就不是5个小时的发挥决定结果了,毫不夸张地说,数模三天,ACM三年.从结果展现来讲,数模是论文优劣定胜负.可能你的成果或者你的答案和评委们手上的"最佳答案&

珍爱生命,远离数模

话说五天四夜的数学建模终于结束了... 珍爱生命,远离数模!哈哈~~ 其实对本次数模并没有抱太大希望,重在参与重在参与. 在实验室看见一组,两个男生意见不同,感觉很不愉快的样子:还有一组,组员都回去了就剩他一个人在默默地做,熬了两个晚上,论文还得自己写,也是蛮辛苦的了,队友说也不是我弄的,所以我也不懂,不知道咋写,那我就先回去了,好坑呀!其实我们小组一开始也挺不愉快的,三个人对题目的理解都不一样,我都无语了...作为一个team,一定得团结! 然后我发现,他们做事好认真啊,不过好像有点太较真了,

数模笔记:公平席位的分配问题

数模笔记:公平席位的分配问题 基础 案列 某展会,AB双方根据人数分配席位: 衡量公平的数量指标: p1/n1=p2/n2.此时对AB均公平. p1/n1>p2/n2.此时对A不公平,因为对A放来说,每个席位相对应的人数比率更大. 绝对不公平度 定义: p1/n1-p2/n2 = 对A的绝对不公平度 问题: /*情况1*/ p1=150, n1=10, p1 /n1=15 p2=100, n2=10, p2 /n2=10 /*情况2*/ p1=1050, n1=10, p1 /n1=105 p2

Fib数模n的循环节 ZOJ Problem Set - 3729 Arnold

Fib数模n的循环节 对于一个正整数n,我们求Fib数模n的循环节的长度的方法如下: (1)把n素因子分解,即 (2)分别计算Fib数模每个的循环节长度,假设长度分别是 (3)那么Fib模n的循环节长度 从上面三个步骤看来,貌似最困难的是第二步,那么我们如何求Fib模的循环节长度呢? 这里有一个优美的定理:Fib数模的最小循环节长度等于,其中表示Fib数模素数的最小循环节长度.可以看出我们现在最重要的就是求 对于求我们利用如下定理: 如果5是模的二次剩余,那么循环节的的长度是的因子,否则,循环节

数模手记 之 MATLAB-入门手记(施工中...)

MATLAB初用起来感觉就是面向矩阵加强版命令行程序,附加高级运算及2D/3D绘图....恩,是的,我就是这样想的= = 博主是个数学系的本科生,也要开始准备暑期的MCM了,虽然本科阶段会开数学软件的课,不过听说比较鸡肋,而且时间比较靠后,所以写一篇手记记录一下自学期间体会比较深刻或感觉比较实用的地方,权当分享和笔记,见笑,哈哈哈. 话说博主为了权衡MCM和ICPC两大竞赛也是费了不少功夫上知乎...... 后来只是觉得想做的事情还是得做啊,数学建模或许会改变我对数学一贯的看法,问了那么多人可能