相关语言、程序导引
Fortran入门快速指南
2006-8-6 相信大家都对C语言有一定的了解,其实Fortran跟C相差不是很多。 我把自己认为比较合理快速学习Fortran的方法说下。 学习Fortran,会遇到Fortran77&Fortran90等等,两者差别不大,建议学习Fortran90或更 高,更加自由些(仅对一般用而言,其他优势可能体现不出来),对自己以后学习他 的程序包也会有好处。 大家一般只是为了编程为了计算而学Fortran,而不是为了学习Fortran而学Fortran,所以 我的建议是学习Fortran不要像学C那样拿一本很详细的教材从头至尾学下来,一个大家都 有不错的C语言基础,而且也没有太多的精力去专门研究这些,倒不如看些简易的教材(我 会附上),掌握基本语句之后直接从看最简单的程序开始。这样,很快就会体会到Fortra n的格式,可以开始自己写程序了。学习的顺序我建议如下: 1、 编一些仅含输入输出的程序,然后可以尝试把输入输出同文件结合起来(从文件里读 数据、写数据); 2、 然后可以学条件判断、循环语句,通过几个实例也可以很快掌握; 3、 再往后就是写子程序,就是程序的调用,相信那个时候,看了我的第一个例子(PROG RAM A)就应该能写出简单的含函数调用的程序,到了这里,基本上可以算告一段落,可以 进行结构上复杂的程序的编写; 4、 最后,可以学一下多个程序的编译甚至是多种语言程序的混编(如既有C又有Fortran 的多个程序一起编译)。多个程序的编译我不并不熟悉,就留给siriusbobo同志来解说吧 :-) 在编程中遇到困难然后再去查找资料和用法不失为一种好的方法,不必刻意去求学全。 当然,有足够时间和精力的同学强烈建议好好看教材,不必急于求成,有一个好的基础总 是一件很好的事。 Fortran相比C的优势的话在于它丰富的资源,C的优势可能是更加简洁,编译效率更高。但 对于我的平时使用来说,这两者的优势、劣势都体现不出来,自己的感觉是Fortran更接近 平时的科学语言,比较严谨些,更容易读懂不出错,比较符合习惯,变量、函数的声明上 也比C更方便灵活,以外函数的使用为例: ****************************************************************************** PROGRAM A real z read *,z call f(z) y=z print *,y end subroutine f(x) x=x**2 return end ****************************************************************************** 只需要加一个"subroutine"程序段,主函数即可用"call"调用,当然也可以写多个子程序 ,其中一个子程序也可以通过"call"来调用其他子程序。 就一般学习而言,除了子程序的编写,另外一个用得比较多的是文件的读写操作,读用 "read",写用"write",如下: ****************************************************************************** PROGRAM B real x open (1,file='in.dat',status='unknown') open (2,file='out.dat',status='unknown') read (1,100) x 100 format (1e12.7) close(1) write (2,200) x 200 format (1e15.8) close(2) end ****************************************************************************** 如果用"*"的话,就为默认形式,更具体的可以查看帮助或有关资料,比较好的方法是随时 做一个test程序,用来检测所学或所想。 对于上程序,出现的"100","200"是语句标号,这些标号为方便语句的跳转而出现,可以实 现循环、条件控制等,但也为了使程序结构化而不推荐使用,用goto语句和语句标号实现 语句的跳转如下: ****************************************************************************** PROGRAM C integer n real z n=0 read *,z 1 call f(z) y=z n=n+1 if (n<10) goto 1 print *,y end subroutine f(x) x=x**2 return end ****************************************************************************** 这类跳转在F77里经常用到,F90以后并不多见,但对于"100 format (1e12.7)"之类还是经 常用到,这是用来表示存储读取的数据的格式的,可以放在程序任何位置,更具体的用法 要参看说明。 有关注释: Fortran里注释用"!"或"C",其中,一般在Windows下使用"Compad Visual Fortran"编译, 有两种格式,一个是"Free Format",生成".f90",另外一个"Fixed Format",生成".for ",只有".for"里两种注释都可用("!"或"C"),但在".f90"里只能用"!"。 有关学习的困难: 算法是语言的灵魂没错,是最麻烦的,但想必大家都学过C,遇到过不少算法,这些可以用 C实现的,用Fortran实现都不是很困难,所以这里不主要讨论这个“灵魂”性质的东西。 常量、变量、数组的数据类型,以及数据类型的读写控制倒是经常容易出错的。下面主要 讲一些我认为需要注意的和我曾经犯过和看到过的错误。 Fortran跟C一样,也分整型(INTEGER),实型(REAL),双精度(REAL*8或REAL(8)或DOUBLE PRECISION),这些在科学计算中还是比较重要的,以实型数为例: 一般REAL等价于REAL*4或REAL(4),是单精度的; 而双精度在F77中表示为DOUBLE PRECISION,在F90中可以表示为REAL*8或REAL(8),在高精 度计算中,双精度的变量是很有必要的,对于一般实数可以表示为小数形式或指数形式, 而双精度都表示成指数形式,但指数E要改成D,如: REAL:100.0或1e2,双精度下就得表示成1D2 由于Fortran中不需要对每个变量都进行声明,所以有时候会在每个程序或子程序开头做个 说明,如下: IMPLICIT DOUBLE PRECISION(A-H,O-Z) 代表以A-H以及O-Z字母开头的变量默认(在不声明的情况下)是双精度的,否则则是整型 的,如下: ****************************************************************************** PROGRAM D IMPLICIT DOUBLE PRECISION(A-H,O-Z) J1=1D-2 J2=-0.5D-1 x=J1+J2 print *,x end ****************************************************************************** PROGRAM E implicit double precision (A-I,O-Z) double precision a,i,e1,e2 data j2 /0.87450547081842D-3/ data j3 /-0.11886910646016D-4/ data j5 /-0.17242068505339D-5/ data j7 /0.10566966079622D-6/ write(*,*) "please input a" read(*,*) a write(*,*) "please input i" read(*,*) i e1=(j3*sin(i)/(2*a*j2)-5*j5*sin(i)*(1-7*sin(i)**2/2+21*sin(i)**4/8)& &/(2*a**3*(2-5*sin(i)**2/2))+35*j7*sin(i)*(1-27*sin(i)**2/4+99& &*sin(i)**4/8-429*sin(i)**6/64)/(3*a**5*(2-5*sin(i)**2/2))) e2=-(j3*sin(i)/(2*a*j2)-5*j5*sin(i)*(1-7*sin(i)**2/2+21*sin(i)**4/8)& &/(2*a**3*(2-5*sin(i)**2/2))+35*j7*sin(i)*(1-27*sin(i)**2/4+99& &*sin(i)**4/8-429*sin(i)**6/64)/(3*a**5*(2-5*sin(i)**2/2))) write(*,"(E9.2E3)") e1,e2 stop end ****************************************************************************** 第一个程序输出不是-0.4而是0.000000000000000E+000 第二个程序任意输入a、i,并未得到希望得到的结果,而是输出NAN和NAN,关于NAN这个错 误,有时候函数定义域不符合的时候,运行并不报错而是输出NAN,这个时候检查程序这些 地方是检查的重点,当然,会有其他情况,但我碰到的不多,只好就我所知跟大家交流一 下。 这两个程序都因为J开头的变量不属于默认双精度变量,而用双精度表示给它们赋值了,导 致结果跟预期不一致,在程序中把这些以J开头的变量用REAL*8声明一下,或把 implicit double precision (A-I,O-Z)改为: implicit double precision (A-J,O-Z),或把这个语句去掉 就可以得到预期的结果了。 对于数组,可以用DIMENSION定义,但需要注意的是,若在程序头未做声明(implicit none)时,用DIMENSION定义数组时,当数组名首字母不属于(A-J,O-Z)里时,其值输出时 为整型,当然做了如下声明情况也会如此:(implicit double precision (A-I,O-Z)) 如下: ****************************************************************************** PROGRAM F dimension m(2) m(1)=1.5 m(2)=2.5 print *,m(1),m(2) end ****************************************************************************** 输出的结果是“1,2”而不是“1.500000,2.500000” 当把程序中m改为a时,输出“1.500000,2.500000” 所以,比较好的方法是尝试用REAL来定义数组(当然也可以用REAL*8): ****************************************************************************** PROGRAM G real m(2) m(1)=1.5 m(2)=2.5 print *,m(1),m(2) end ****************************************************************************** 另外,要说的是,变量可以不定义而直接赋值,但会出现如上面PROGRAM D-E的问题,所以 建议大家在编程的时候对非整型变量声明一下,尽管麻烦,但不容易出错,有时候正是这 类错误会让初学者困扰好久。 定义变量时,经常会看到两种定义的写法:以REAL为例: 可以有 real m 和 real:: m 第一种方式不可以直接赋值,必须写成这样: ****************************************************************************** PROGRAM H real m m=1.0 print *,m end ****************************************************************************** 第二种则可以: ****************************************************************************** PROGRAM I real:: m=1.0 print *,m end ******************************************************************************
Free Fortran Compilers
取自 http://www.thefreecountry.com/compilers/fortran.shtml
This page lists free Fortran compilers for various operating systems. Some of the compilers are compliant with the ANSI Fortran 77 specifications, others with Fortran 95, and so on. Some of them may also come complete with debuggers, editors and an integrated development environment (IDE).
If you need a book on Fortran, you may want to check out the selection of books available at Amazon.com.
Disclaimer
The information provided on this page comes without any warranty whatsoever. Use it at your own risk. Just because a program, book or service is listed here or has a good review does not mean that I endorse or approve of the program or of any of its contents. All the other standard disclaimers also apply.
Free Fortran Compilers and IDEs
Sun Studio Compilers and Tools for Linux and Solaris OS on Sparc and x86/x64 platforms includes command line tools as well as a NetBeans-based IDE for developing, compiling and debugging C, C++ and Fortran programs. It also includes performance analysis tools.
The Intel Fortran Compiler for Linux is free for personal, non-commercial use (registration required). It features an optimizing compiler, the Intel Debugger (GUI and command-line), mixed language support (C and Fortran), full compliance with the ISO Fortran 95 standard, support for the evolving Fortran 2003 standard, multi-threaded application support (OpenMP and auto-parallelization), ability to handle big-endian data files, compatibility with various Linux tools (like make, gdb and Emacs), substantial compatibility with Compaq Visual Fortran, etc. The optimizing compiler supports interprocedural optimization, profile guided optimization, automatic vectorizer, etc.
G95 is an open source Fortran 95 compiler. At the time this was written, most of the ISO Fortran 95 standard has been implemented. Platforms supported include Linux(x86, Intel IA64, AMD x86_64), Windows, Macintosh OS X, FreeBSD, Sparc Solaris and HP-UX.
gfortran is a Fortran 95 compiler. It runs on Linux and Windows (under cygwin).
Salford FTN95 is a Fortran 95 compiler that supports Fortran 77, Fortran 90 and Fortran 95. The compiler generates exectuables for Win32 (but Win32 console and GUI applications) and the Microsoft .NET framework. It comes with CHECKMATE, a tool that lets programmers check the correctness of their code at runtime. Also included is Plato 3 (an IDE), full source level debugging, documentation and examples. You may only generate code for your personal use on your home computer, and all executables will display a banner on execution.
The Salford FTN77 PE (Personal Edition) comes with a full optimising ANSI Fortran 77 compiler with support for various common extensions (including MIL-STD-1753), linker, libraries, make utility, librarian and a full screen debugger. The compiler has a built-in assembler for inline assembly, and the ability to link with code from other sources (such as C++ Fortran 90 and Fortran 95 code). It is free for personal use and for use by students. It supports Windows 95, 98 and NT.
The Watcom (now OpenWatcom) Fortran 77 compiler is now available free of charge, complete with source code. This compiler, which generates code for Win32, Windows 3.1 (Win16), OS/2, Netware, MSDOS (16 and 32 bit), etc, was a well-known compiler some years back (until Sybase terminated it).
This system comes with the GNU G77 Fortran compiler (among other things, including a C/C++ compiler), which you can use to generate Win32 executables from F77 code. Like many systems based on the GNU tools, Mingw32 comes with complete with various programming tools, such as a program maintainence program (ie, make), text processing tools (sed, grep), lexical analyser generator (flex), parser generator (bison), etc.
This is a development system based on the well-known GNU compiler system that includes compilers for Fortran 77, C, C++, Objective C, etc. It generates 32 bit MSDOS executables that is Windows 95 long-filename-aware. It is a very complete system with IDEs, graphics libraries, lexical analyser generators (flex), parser generators (bison), text processing utilities (like grep, sed), a program maintainence utility (ie, make), a dos extender, and so on. The compiler, utilities and libraries come with source code.
f2j translates Fortran 77 source code to Java class files. It is distributed under the GNU GPL and runs on Linux, SunOS/Solaris.
This is a well-known Fortran to C converter that comes with source code. The site also includes pre-compiled binaries (executables) for MSDOS and Microsoft Windows, although these are by no means the only systems supported - the compiler works on Unix systems like BSD, Linux, etc. You have to compile the compiler yourself on those systems. Libraries containing the runtime support needed (together with the C source code) are also included. You need a C compiler to generate binaries from your Fortran sources.
FORCE is actually just an IDE for Fortran 77 that integrates the GNU Fortran 77 compiler (G77).
This is another GNU Fortran port. The RSX port compiles DOS extended console applications for Win32 and the EMX port generates MSDOS extended applications as well as OS/2 applications. The compiler supports the Fortran 77 syntax.
LCC-Win32 is primarily a free C compiler and its programming environment for Win32, but it also appears to have a Fortran compiler available for download from their website. It apparently compiles Fortran 77 code (with some common extensions) to C which is subsequently compiled by the C compiler to generate a Win32 native executable. The entire process is integrated seamlessly into the IDE so you might not even realise that intemediate C files were being generated (they are deleted automatically when they are no longer needed). The IDE supports syntax highlighting in C and Fortran.
This Fortran compiler is for Linux Alpha systems only. It implements the full Fortran-95 language as well as a few language extensions. It comes with a debugger (ladebug), an extended maths library (the Compaq Extended Math Library, CXML) containing technical and scientific subroutines. The licence for the free version allows it to be used for personal and educational purposes, and prohibits its use in any commercial venture.
作者:gator
目录: 一、说明 二、概述 三、数据类型及基本输入输出 四、流程控制 五、循环 六、数组 七、函数 八、文件
一、说明 本文多数内容是我读彭国伦《Fortran 95 程序设计》的笔记。只读到第九章,主要是3~9 章,都是最基本的用法(原书共16章)。这里主要摘录了我看书过程中总结的一些Fortran和C不 同的地方,主要是语法方面。希望这份笔记能够给学过C但没有接触过Fortran的同学带去一些帮 助。要想得更清楚些,推荐看一下原书,觉得作者真的写得很好,很清楚;如果有C语言的基础, 看完前九应该很快的,花一两天就行了。觉得如果耐心看完本文,基本功能应该也可以顺利用起 来了。外,由于我之前没有用过Fortran,这次为了赶文档看书又看得很粗浅,大多数东西看过 之后都没得及仔细想,只是按着作者的意思去理解。所以这份笔记还处于纸上谈兵的层次。如果 有不妥的方,希望大家指正。谢谢! 文中蓝色的部分是程序代码,!后面的内容为注释。
二、概述 1、名词解释 Fortran=Formula Translator/Translation 一看就知道有什么特色了:可以把接近数学语言的文本翻译成机械语言。的确,从一开始 ,IBM设计的时候就是为了方便数值计算和科学数据处理。设计强大的数组操作就是为了实现这一 目标。ortran奠定了高级语言发展的基础。现在Fortran在科研和机械方面应用很广。
2、Fortran的主要版本及差别 按其发展历史,Fortran编译器的版本其实很多。现在在广泛使用的是Fortran 77和Fortr an90。ortran 90在Fortran 77基础上添加了不少使用的功能,并且改良了77编程的版面格式, 所以编程时推荐使用90。鉴于很多现成的程序只有77版本,有必要知道77的一些基本常识,至少保 证能够看77程序。以下是77和90的一些格式上的区别。 Fortran 77: 固定格式(fixed format),程序代码扩展名:.f或.for (1)若某行以C,c或*开头,则该行被当成注释; (2)每行前六个字符不能写程序代码,可空着,或者1~5字符以数字表明行代码(用作格 式化输入出等);7~72为程序代码编写区;73往后被忽略; (3)太长的话可以续行,所续行的第六个字符必须是"0"以外的任何字符。 Fortran 90:自由格式(free format), 扩展名:.f90 (1)以"!"引导注释; (2)每行可132字符,行代码放在每行最前面; (3)以&续行,放在该行末或下行初。 以下都是讨论Fortran 90。
3、Fortran的一些特点,和C的一些不同
其实很多,在下面涉及具体方面时可以看到。这里只是大致提一些。
(1)不分大小写
(2)每句末尾不必要写分号
(3)程序代码命令间的空格没有意义
(4)不像C,Fortran不使用{ }
(5)数据类型多出了复数和逻辑判断类型。比如复数类型
complex :: a !声明复数的方法。复数显然方便了科学计算,满足了工程方面需求
a=(1.0,2.0) ! a=1+i
(6)多出了乘幂运算(**)。乘幂除了整数还可以是实数形式。如开方,开立方
a=4.0**0.5,a=8.0**(1.0/3.0)。
(7)数组有一些整体操作的功能;可以方便的对部分元素进行操作
(8)有些情况下可以声明大小待定的数组,很实用的功能
4、Fortran的基本程序结构 先看一看所谓的"Hello Fortran"程序。 program main !程序开始,main是program的名字,完全自定义 write(*,*) "Hello" !主程序 stop !终止程序 end [program[main]] !end用于封装代码,表示代码编写完毕。[ ]中的内容可省略,下同。 再看一段实用一些的程序,好有点感性认识。程序用于计算圆柱的表面积,要求输入底面 半径和。其中展示了Fortran的一些特色用法。程序摘自维基。其实是一个叫www.answers.com 的网上引的维基的网页。推荐去看看!能查到不少有意思的东西。 program cylinder !给主函数起个名字 ! Calculate the area of a cylinder. ! Declare variables and constants. ! constants=pi ! variables=radius squared and height implicit none ! Require all variables to be explicitly declared !这个一般都是要写上的。下面会进一步说明。 integer :: ierr character :: yn real :: radius, height, area real, parameter :: pi = 3.1415926536 !这是常量的声明方法 interactive_loop: do !do循环,Fortran中的循环可以加标签,如d前面的 !interactive_loop就是标签
! Prompt the user for radius and height
! and read them.
write (*,*) 'Enter radius and height.' !屏幕输出
read (*,*,iostat=ierr) radius,height !键盘输入。isotat的值用判断输入成功否。
! If radius and height could not be read from input,
! then cycle through the loop.
if (ierr /= 0) then
write(*,*) 'Error, invalid input.'
cycle interactive_loop !cycle 相当于C里的continue
end if
! Compute area. The ** means "raise to a power."
area = 2 * pi * (radius**2 + radius*height) ! 指数运算比C方便
! Write the input variables (radius, height)
! and output (area) to the screen.
write (*,'(1x,a7,f6.2,5x,a7,f6.2,5x,a5,f6.2)') &
!"&"表示续行。这里还显示了格式化输出 'radius=',radius,'height=',height,'area=',area yn = ' ' yn_loop: do !内嵌的另一个do循环 write(*,*) 'Perform another calculation? y[n]' read(*,'(a1)') yn if (yn=='y' .or. yn=='Y') exit yn_loop if (yn=='n' .or. yn=='N' .or. yn==' ') exit interactive_loop end do yn_loop !结束内嵌do循环 end do interactive_loop end program cylinder Fortran程序的主要结构就是这样了。一般还会有些module的部分在主函数前,函数在主函 数后。
三、数据类型及基本输入输出 1、数据类型,声明及赋初值 (1)integer: 短整型kind=2, 长整型kind=4 integer([kind=]2) :: a=3 如果声明成integer:: a,则默认为长整型。 !"::" 在声明并同时赋初值时必须要写上;类型名后面有形容词时也必须保留::;其他情况可略去 !所谓形容词,可以看一下这个。比如声明常数 real,parameter :: pi=3.1415926 。parameter就是形容词。 (2)real:单精度kind=4(默认),双精度kind=8 real([kind=]8) :: a=3.0 还有指数的形式,如1E10为单精度,1D10为双精度 (3)complex 单精度和双精度 complex([kind=]4) b (4)character character([len=]10) c !len为最大长度 (5)logical logical*2 :: d=.ture. (等价于logical(2)::d=.ture.) (6)自定义类型type:类似于C中的struct Fortran 77中给变量赋初值常用DATA命令,可同时给多个变量赋初值 data a,b,string /1, 2.0, 'fortran'/ 与C不同的是,Fortran中变量不声明也能使用,即有默认类型(跟implicit命令有关)。按 照默认的定,以i,j,k,l,m,n开头的变量被定义为integer,其余为real。取消该设置需在程序声明 部分之前implicit none。彭国伦建议一般都使用该语句。 另一点关于声明的不同是Fortran有"等价声明": integer a,b equivalence(a,b) 使得a,b使用同一块内存。这样可以节省内存;有时可精简代码。如:equivalence(很长名 字的变量如三维数组的某个元素,a),之后使用a来编写程序就简洁多了。
2、基本输入输出 输入:read(*,*) a !从键盘读入 输出:write(*,*) "text" !在屏幕上输出。Fortran 77用' text'。Fortan 90中一般" "和' '都可 print *,"text" !只能用于屏幕输出 (*,*)完整写为(unit=*,fmt=*)。其中unit为输入/输出位置,如屏幕,文件等;fmt为 格式。如这两项都写成*,则按默认的方式进行,即上面描述的。print后面的*表示按默认格式输 出。
四、流程控制 1、运算符 (1)逻辑运算符 == /= > >= < <= !Fortran 90用法 .EQ. .NE. .GT. .GE. .LT. .LE. !Fortran 77用法 (2)涉及相互关系的集合运算符 .AND. .OR. .NOT. .EQV. .NEQV. ! 仅.NOT.连接一个表达式,其余左右两边都要有表达式(可以是logical类型的变量) !.EQV.:当两边逻辑运算值相同时为真, .NEQV.:当两边逻辑运算值不同时为真
2、IF
(1) 基本 :
if(逻辑判断式) then
……
end if
如果then后面只有一句,可写为
if(逻辑判断式) …… !then和end if可省略
(2) 多重判断:
if(条件1) then
……
else if(条件2)then
……
else if (条件3)then
……
else
……
end if
(3) 嵌套:
if(逻辑判断式) then
if(逻辑判断式) then
if(逻辑判断式) then
else if(逻辑判断式) then
……
else
……
end if
end if
end if
(4) 算术判断:
program example
implicit none
real c
write (*,*) "input a number"
read (*,*) c
if(c) 10,20,30 !10,20和30为行代码,根据c小于/等于/大于0,执行10/20/30行的程
10 write (*,*) "A"
goto 40 !goto可实现跳到任意前面或后面的行代码处,但用多了破坏程序结
20 write (*,*) "B"
goto 40
30 write (*,*) "C"
goto 40
40 stop
end
3、SELECT CASE
类似于C的switch语句
select case(变量)
case(数值1) ! 比如case(1:5)代表1<=变量<=5会执行该模块
…… !case(1,3,5)代表变量等于1或3或5会执行该模块
case(数值2) !括号中数值只能是integer,character或logical型常量,不能real型
…
case default
……
end case
4、PAUSE, CONTINUE pause暂停程序执行,按enter可继续执行 continue貌似没什么用处,可用作封装程序的标志
五、循环 1、DO do counter=初值, 终值, 增/减量 !counter的值从初值到终值按增/减量变, …… !counter每取一个值对应着一次循环。增/减量不写则认为1 …… …… !循环主体也没有必要用{} …… end do Fortran 77中不是用end do来终止,而是下面这样子: do 循环最后一行的行代码 counter=初值, 终值, 增/减量 …… 行代码 …… !这是do的最后一行
2、DO WHILE
do while(逻辑运算)
……
……
end do
类似于C中的while(逻辑运算) {……}。
一开始那个计算圆柱表面积的程序中,应该也算是这一类。不过它是通过内部的if语句来
控制循。看来也是可以的,不过在这本书上没看到这样写。其实应该也可以归于下面这种。
3、没看到和C里面的do{……}while(逻辑运算); 相对应的循环语句,不过可以这样,保证
至少做一循环:
do while(.ture.)
……
……
if(逻辑运算) exit !exit就好比C里面的break。C里的continue在Fortran里是cycle
end do
4、Fortran的一个特色:带署名的循环 可以这样,不易出错: outer: do i=1,3 inner: do j=1,3 …… end do inner end do outer 还可以这样,很方便: loop 1: do i=1,3 loop2: do j=1,3 if(i==3) exit loop1 !exit终止整个循环loop1 if(j==2) cycle loop2 !cycle跳出loop2的本次循环,进行loop2的下次循环 write(*,*) i,j end do loop2 end do loop1 还有一些循环主要用于Fortran中的数组运算,为Fortran特有,很实用。
六、数组 1、数组的声明 和C不同的是,Fortran中的数组元素的索引值写在()内,且高维的也只用一个(),如 integer a(5) !声明一个整型一维数组 real :: b(3,6) !声明一个实型二维数组 类型可以是integer, real, character, logical或type。最高可以到7维。 数组大小必须为常数。但是和C语言不同,Fortran也有办法使用大小可变的数组,方法如: integer, allocatable :: a(:)
!声明小可变经过某个途径得知所需数组大小size之后,用下面的语句: allocate(a(size)) !配置内存空间 之后该数组和通过一般方法声明的数组完全相同。 与C不同,Fortran索引值默认为从1开始,而且可以在声明时改变该规则: integer a(-3:1) ! 索引值为-3,-2,-1,0,1 integer b(2:3,-1:3) !b(2~3,-1~3)为可使用的元素
2、数组在内存中的存放 和C不同,Fortran中的数组比如a(2,2)在内存中存放顺序为a(1,1),a(2,1),a(1,2),a(2,2 )。原则是放低维的元素,再放高维的元素。此规则称为column major。
3、赋初值 (1)最普通的做法: integer a(5) data a /1,2,3,4,5/ 或integer :: a(5)=(/1,2,3,4,5/) 若integer :: a(5)=5,则5个元素均为5 对于integer :: a(2,2)=(/1,2,3,4/) 根据数组元素在内存中存放的方式,等价于赋值a(1,1)=1,a(2,1)=2,a(1,2)=3,a(2,2)=4 (2)利用Fortran的特色:隐含式循环。看例子就明白了。 integer a(5) integer i data (a(i),i=2,4)/2,3,4/ !(a(i),i=2,4)表示i从2到4循环,增量为默认值1 还可以这样: integer i integer :: a(5)=(/1,(2,i=2,4),5/) !五个元素分别赋值为1,2,2,2,5 integer :: b(5)=(/i, i=1,5/) !五个元素分别赋值为1,2,3,4, 还可以嵌套 data ((a(i,j),i=1,2),j=1,2)=/1,2,3,4/ !a(1,1)=1,1(2,1)=2,a(1,2)=3,a(2,2)=4
4、操作整个数组 设a,b为相同类型、维数和大小的数组 a=5 !所有元素赋值为5 a=(/1,2,3/) !这里假设a为一维,a(1)=1,a(2)=2,a(3)=3 a=b !对应元素赋值,要求a,b,c维数和大小相同,下同 a=b+c a=b-c a=b*c a=b/c a=sin(b) !内部函数都可以这样用
5、操作部分数组元素 a为一维数组 a(3:5)=(/3,4,5/) !a(3)=3,a(4)=4,a(5)=5 a(1:5:2)=3 !a(1)=3,a(3)=3,a(5)=3 a(3:)=5 !a(3)以及之后的所有元素赋值为5 a(1:3)=b(4:6) !类似于这种的要求左右数组元素个数相同 a(:)=b(:,2) !a(1)=b(1,2),a(2)=b(2,2),以此类推
6、WHERE where形式上类似于if,但只用于设置数组。设有两个同样类型、维数和大小的数组a,b where(a<3) b=a !a中小于3的元素赋值给b对应位置的元素 end where 再如:where(a(1:3)/=0) c=a !略去了end where,因为只跟了一行where可嵌,也 !可类似do循环有署名标签。
7、FORALL 有点像C中的for循环: forall(triplet1[,triplet2 [,triplet3…]],mask) 其中triplet形如i=2:6:2,表示循环,最后一个数字省略则增量为1 例如: forall(i=1:5,j=1:5,a(i,j)<10) a(i,j)=1 end forall 又如: forall(i=1:5,j=1:5,a(i,j)/=0) a(i,j)=1/a(i,j) forall也可以嵌套使用,好比C中for循环的嵌套。
七、函数 Fortran中函数分两类:子程序(subroutine)和自定义函数(function)。自定义函数本 质上就是学上的函数,一般要传递自变量给自定义函数,返回函数值。子程序不一定是这样,可 以没有返值。传递参数要注意类型的对应,这跟C是一样的。 1、子程序 目的:把某一段经常使用的有特定功能的程序独立出来,可以方便调用。 习惯上一般都把子程序放在主程序结束之后。 形式: subroutine name (parameter1, parameter2) !给子程序起一个有意义的名字。可以传递参数,这样可以有返回值。括号内也可以 空着,代不传递参数。 implicit none integer:: parameter1, parameter2 !需要定义一下接收参数的类型。 …… !接下来的程序编写跟主程序没有任何别。 …… mreturn !跟C不同,这里表示子程序执行后回到调用它的地方继续执行下面的程序。不一定放
!在最后。可以放在子程序的其他位置,作用相同;子程序中return之后的部分不执行。
end [subroutine name]
调用:使用call命令直接使用,不需要声明。在调用处写:
call subroutine name(parameter1,parameter2)
注意点:
a.子程序之间也可相互调用。直接调用就是了,像在主程序中调用子程序一样。
b.传递参数的原理和C中不同。Fortran里是传址调用(call by address/reference),就是
传递时用参数和子程序中接收时用的参数使用同一个地址,尽管命名可以不同。这样如果子程序
的执行改子程序中接收参数的值,所传递的参数也相应发生变化。
c.子程序各自内部定义的变量具有独立性,类似于C。各自的行代码也具有独立性。因此各
个子程序主程序中有相同的变量名、行代码号,并不会相互影响。
2、自定义函数 和子程序的明显不同在于:需要在主程序中声明之后才能使用。调用方式也有差别。另外 按照惯例用函数不去改变自变量的值。如果要改变传递参数的值,习惯上用子程序来做。 声明方式:real, external :: function_name 一般自定义函数也是放在主程序之后。 形式: function function_name(parameter1, parameter2) implicit none real:: parameter1, parameter2 !声明函数参数类型,这是必需的 real::function_name !声明函数返回值类型,这是必需的 …… …… function_name=…. !返回值的表达式 return end 也可以这样直接声明返回值类型,简洁些: real function function_name(parameter1, parameter2) implicit none real:: parameter1, parameter2 !这个还是必需的 …… …… function_name=…. !返回值表达式 return end 调用:function_name(parameter1,parameter2) 不需要call命令。 自定义函数可以相互调用。调用时也需要事先声明。 总之,调用自定义函数前需要做声明,调用子程序则不需要。
3、关于函数中的变量 (1)注意类型的对应。Fortran中甚至可以传递数值常量,但只有跟函数定义的参数类型 对应才会到想要的结果。如call ShowReal(1.0)就必须用1.0而不是1。 (2)传递数组参数,也跟C一样是传地址,不过不一定是数组首地址,而可以是数组某个 指定元素地址。比如有数组a(5),调用call function(a)则传递a(1)的地址,调用call functio n(a(3))则递a(3)的地址。 (3)多维数组作为函数参数,跟C相反的是,最后一维的大小可以不写,其他维大小必须 写。这决于Fortran中数组元素column major的存放方式。 (4)在函数中,如果数组是接收用的参数,则在声明时可以用变量赋值它的大小,甚至可 以不指定小。例如: subroutine Array(num,size) implicit none integer:: size integer num(size) !可以定义一个数组,其大小是通过传递过来的参数决定的。这很实用 …… …… return end (5)save命令:将函数中的变量值在调用之后保留下来,下次调用此函数时该变量的值就 是上次保的值。只要在定义时加上save就行: integer, save :: a=1 (6)传递函数(包括自定义函数、库函数、子程序都是可以的)。类似于C中的函数指针需要在 主程序和调用函数的函数中都声明作为参数传递的函数。如 real, external :: function !自定义函数 real, intrinsic :: sin !库函数 external sub !子程序 (7)函数使用接口(interface):一段程序模块。以下情况必需: a.函数返回值为数组 b.指定参数位置来传递参数时 c.所调用的函数参数个数不固定 d.输入指标参数时 e.函数返回值为指针时。 具体用法结合例子容易看懂。例子都很长。看书吧。
4、全局变量
功能就不用说了。原理:根据声明时的相对位置关系而取用,不同与C中根据变量名使用。
如果在主程序中定义:
integer :: a,b
common a,b !就是这样定义全局变量的
在子程序或自定义函数中定义:
integer :: c,d
common c,d
则a和c共用相同内存,b和d共用相同内存。
全局变量太多时会很麻烦。可以把它们人为归类,只需在定义时在common后面加上区间名
。如
common /groupe1/ a, common /group2/ b。这样使用时就不必把所有全局变量
都列出来,再声明common /groupe1/ c就可以用a、c全局变量了。
可以使用block data程序模块。在主程序和函数中不能直接使用前面提到的data命令给全
局变量赋初值。可以给它们各自赋初值;如果要使用data命令必须要这样:
block data [name]
implicit none
integer a,b,c
real d,e
common a b c
common /group1/ d,e
data a,b,c,d,e /1,2,3,4.0,5.0/
end [block data [name]]
5、Module
Module不是函数。它用于封装程序模块,一般是把具有相关功能的函数及变量封装在一起
。用法很单,但能提供很多方便,使程序变得简洁,比如使用全局变量不必每次都声明一长串,
写在odule里调用就行了。Module一般写在主程序开始之前。
形式:
module module_name
……
……
end [module [module_name]]
使用:在主程序或函数中使用时,需要在声明之前先写上一行:use module_name.
Module中有函数时必须在contains命令之后(即在某一行写上contains然后下
面开始写数,多所有函数都写在这个contains之后)。并且module中定义过的变量在module里的
函数中可直接使用,函数之间也可以直接相互调用,连module中的自定义函数在被调用时也不用
先声明。
6、include放在需要的任何地方,插入另外的文件(必须在同一目录下)。如:
include 'funcion.f90'
八、文件 1、文本文件 Fortran里有两种读取文件的方式,对应于两种文件 顺序读取:用于文本文件 直接读取:用于二进制文件 这里只摘录关于文本文件的读取。一般模式如下。 character(len=20)::filenamein="in.txt", filenameout="out.txt" !文件名 logical alive integer::fileidin=10,fileidout=20 !10,20是给文件编的号,除1,2,5,6的正整数都可,因为2、6是默认的输出位置(屏幕 ),1、5是默认的输入位置(键盘) integer::error real::in,out !下面这一段用于确认指定名字的文件是否存在 inquire(file=filenamein, exist=alive) !如果存在,alive赋值为0 if(.NOT. alive) then write(*,*) trim(filenamein), " doesn't exist."!trim用于删去filenamein中字串 !后面的stop多余空格,输出时好看些 end if open([unit=]fileidin, file=filenamein, status="old") open([unit=]fileidout,file=filenameout[,status="new"]) !unit指定输入/输出的位置。打开已有文件一定要用status="old";打开新文件用status="new"; !不指定status,则默认status="unknown",覆盖已有文件或打开新文件…… read([unit=]fileidin, [fmt=]100,iostat=error )in !error=0表示正确读入数据。 100 format(1X,F6.3) !按一定格式输入输出,格式可以另外写并指定行代码,也可以直接写在read/write中 write(([unit=]fileidout, "(1X,F6.3)")out close(fileidin) close(fileidout) !1X代表一个空格。F6.3代表real型数据用占6个字符(含小数点),其中小数点后三位。 !常用的还有I3,用于整型数据,共占三个字符;A8,字符型,占8个字符。换行用 / 二进制文件的读取有所不同。不再列举。
2、内部文件 另一个很实用的读写功能是内部文件(internal file)。看看这个例子就明白了。 integer::a=1,b=2 character(len=20)::string write(unit=string,fmt="(I2,'+',I2,'=',I2)")a,b,a+b write(*,*)string 则结果输出1+2=3。反过来也是可以的: integer a character(len=20)::string="123" read(string,*)a write(*,*)a 则输出123。
!全文结束。
IDL快速入门及相关资源
作者:蒋雪健
美国RSI公司(现并入ittvis--编者注)的旗舰产品--IDL(Interactive Data Language) 交互式数据语言是进行二维及多维数据可视化表现、分析及应用开发的理想软件工具。作 为面向矩阵、语法简单的第四代可视化语言,IDL致力于科学数据的可视化和分 析,是跨平台应用开发的最佳选择。 早在1982年NASA的火星飞越航空器的开发就使用IDL软件,到现在IDL已经被列为国外 许多大学的标准课程,IDL使科研人员无须编写传统程序就可直接研究数据 一、IDL语言是什么? 简单的说,IDL是VC、VB、JAVA、FORTRAN、MATLAB、OPENGL等语言的集成。 1、IDL =VC 从菜单的定制、消息的传递、类的定义与继承等方面来说,IDL如同VC一样具备了强大 的功能。 2、IDL=VB 从可视化界面的设计、语言的通俗易懂、编程的入门等方面来说,IDL如同VB一样,让 初学者心旷神怡。 3、IDL=JAVA 从跨平台的移植来说,IDL的功能与JAVA一样强大。应用IDL开发的产品,只要微不足 道的工作就可以在各平台之间任逍遥。 4、IDL=FORTRAN FORTRAN语言是科学计算领域一门最普遍的语言,是科学家最为广泛应用的语言。从函 数、子程序的调用、数据传递、语言风格、语言组织等来说,IDL语言与FORTRAN则是如此 的相像,见到了IDL,你就会想起FORTRAN语言。 5、IDL=MATLAB IDL语言象MATLAB一样,提供了大量封装和参数化了的数学函数,为科学计算插上了强 大的翅膀。 6、IDL=OPENGL IDL的提供了丰富的二维、三维图形图像类,其功能可与OPENGL媲美,而且其封装好的 图形函数类的编程功能远超过OPENGL函数库。 同时IDL又是如此完美的ActiveX控件,在VB、VC中通过ActiveX控件技术能完整的再现 IDL的丰富而又巨大的功能。 此外,从另一种意义上说,IDL语言与大型图形和GIS应用软件相距又是如此之近。应 用IDL可以快速的开发出功能强大的三维图形图像处理软件和三维GIS应用系统。 二、IDL语言能干什么? 由于其强大的功能和独特的特点,IDL语言可以应用于任何领域的三维数据可视化、数 值计算、三维图形建模、科学数据读取等功能中。 概括说来,在地球科学(包括气象、水文、海洋、土壤、地质、地下水等)、医学影 像、图像处理、GIS系统、软件开发,大学教学,实验室,测试技术,天文,航空航天、信 号处理,防御工程,数学统计及分析,环境工程等很多领域,IDL语言都可以得到广泛而又 深远的应用。 三、IDL已干出了什么? 目前应用IDL语言,已经开发出了ENVI、IMAGIS、RiverTools、医学等成熟产品。具体 的应用实例也非常多,如在2000年澳大利亚悉尼奥运会综合预报系统、美国国家环境卫星 数据和信息服务中心的厄尔尼诺现象分析等工作中得到了成功的应用。 作为面向矩阵、语法简单的第四代可视化语言,IDL致力于科学数据的可视化和分析,是跨 平台应用开发的最佳选择。它集可视化、交互分析、大型商业开发为一体,为用户提供完 善、灵活、有效地开发环境。 IDL在数字信号与图像处理的优势: 1.高级的智能工具箱 iTools(intelligent tools)的出现是IDL6.0向易用性和易扩展性迈出的重要一步。我们可 以引用Mohsen Farid 博士的一句话给予iTools精确的描述:“iTools are excellent in teractive visualization tools that allow complete interactivity and control ov er datasets. iTools are well suited for exploratory type work。” 以往版本的IDL对于数据的可视化工作对采用直接图形法和命令行的方式,虽然简单快捷并 且得到了一批用户的认可,但是面对计算机应用水平的不断提高,更多的用户选择基于鼠 标即可完成的简单操作,而不是需要键入指令,iTools则应运而生。iTools是由一批工具 箱组成,其中包括iPlot、iSurface、iContour、iImage、iVolume等等。IDL使用者可以通 过鼠标进行拖放即可完成数据的可视化以及分析工作。 2.极高的运算效率 IDL采用面向矩阵的技术,具有高效编程特点的同时,自动支持多CPUs机制,可以大大提高 计算速度。另外,由于IDL对于数据类型的要求比较灵活,可以避免Matlab中强制64Bit参 与计算的瓶颈,使得IDL更加适用于工程计算和相关软件的开发。 3.支持海量数据 随着计算机应用水品的不断提高,人们数据量的要求也在不断提高。一些朋友反映说好像 IDL对于开辟矩阵的大小有些置疑,这里我需要补充一下。大部分朋友是受了硬件厂商的错 觉,硬件厂商宣称自己的计算机能够有多大的内存,实际上是指内存的管理而不是说明能 够一次开辟这么大的矩阵。并且,还有一些操作系统方面的限制。举例说明,Windows系列 都是32位的操作系统,一次性最大开辟内存是2G,除了系统本身占用资源外,最多能够开 到1.2-1.5G就非常不错了,因此,由此看来,IDL在利用内存上还是不错的。如果在64位 的操作系统上,问题就会得到缓解。有人曾经在Linux上测试,利用IDL开辟4G的矩阵没有 问题。由此完全客服了数据量的瓶颈限制和分块读取的麻烦。 4.灵活的外部语言接口 做为高级的语言工具,IDL提供丰富而灵活的语言接口。可以与C、C++、Fortran、VB、 Java、VC等商业开发平台进行相互调用,尤其是IDL中Java Bridge技术,可以在IDL编程环 境中直接创建和管理Jave的对象。与此同时,IDL还可以直接调用IMS以及Lapack等算法库 ,使得科学计算与分析更为方便快捷。 与此同时,IDL还提供数据库的标准接口,可以对各种大型商业数据进行管理以及的高级应 用开发。 *********************************************************** 下面是我搜集的一些材料: http://pickup.mofile.com/3673637294742152 匿名提取文件 或登录Mofile,使用提取码 3673637294742152 提取文件 (不保证永远有效,如需下载但发现无效请与我联系)
Matlab快速入门以及相关天文资源
索引:
打开Matlab,你所看到的最主要部分是一大块命令窗口。我们就从这个命令窗口为中心,让你五分钟内会用matlab。此文只是懒人的入门手册,并非参考手册。一个简明的参考手册可以看比邻星的我的Matlab基本用法小结。入门后进一步可参考帮助文档来边用边学。
2+3然后回车,得到ans=5。+ -* /^ (幂指数可以是整数和小数,可正可负)x=5则将x赋值5。变量不需事先声明或者定义,随写随用。
5:10, 20:10, 1.5:-0.5:-2分别看看效果。a:b:c这样一个序列表示从起点a开始每次变化b步长直到终点c的一个数组。A=[4,3,2,1;11,12,13,14]将得到如下矩阵| 4 | 3 | 2 | 1 |
| 11 | 12 | 13 | 14 |
要点:在[]内输入元素,以;或者换行来区分不同行,以逗号或者空格来区分不同元素。
- 整体引用:直接用变量名。比如
A+3,表示对矩阵所有元素+3
- 元素引用:
A(2,3)表示A的第2行第3列元素。
- 嵌套引用:可以用一维数组作矩阵的下标来对元素进行批量引用。比如
A(1:2:9, 2:2:10)=0表示将A的前面10x10个元素中的奇数行偶数列赋值为0。A([1,7],2)表示A的1行和7行的第二列元素。
- 分块赋值:对矩阵赋值时,可以使用已有的矩阵或当场产生的矩阵来对矩阵分块赋值。比如
A=[4:1;11:14]等价于A=[4,3,2,1;11,12,13,14]。B=[A;21:24]等价于B=[4:1;11:14;21:24]。
- 整体运算:
A*B, A+B,A'(转置),inv(A)(逆阵) A^5
- 元素运算:整体运算符前面加一点可以用在两个相同形状的矩阵之间,表示对应元素之间的运算。也可以用在数与矩阵之间,表示数同矩阵每个元素之间的运算。
.* ./ .^
matlab的所有单个命令都可以放在一个.m后缀的文件中依次执行,这就构成一个脚本文件。是为编程。
例:执行命令:
edit mycmd.m输入
x=[] for i=1:3 x=[x,i] end x=x-4; %百分号后面为注释;语句后加分号抑制语句执行结果在命令行的输出保存到默认目录下,然后在命令行输入mycmd执行该脚本。
循环:
for 变量=循环数组 ...(执行) end判断:
if(条件) ....(执行) else ....(执行) endif可以嵌套。
其中条件为逻辑表达式,如:x>1(大于), a<b(小于),z~=3(不等于), x>1&x<3(且), t<1|t>5(或)
save myfile 将当前数据保存为myfile.mat使用
load myfile将myfile.mat 中的数据导入当前工作区。
例:
x=mean(A) %求矩阵A的每一列的均值。 a=1:10;b=a.*2;plot(a,b) %绘制以a为横坐标,b为纵坐标的曲线。 ezplot('sin(x)+x*cos(x)') %,试试效果。
随时使用你的右键菜单,看看有何收获。
注意窗口上的各个菜单,试验看看有何功能。
Matlab7之后,对数据的输入输出以及各种图形的绘制,基本上都可以很轻松的在workspace中通过相应按钮或者右键菜单完成。甚至图形的创建都可以在图像窗口中拖拽完成。
- 输入doc命令,打开帮助。搜索你需要的关键字,或者分类浏览。Matlab的帮助文档里有你需要的所有信息。以后matlab的帮助就是你的matlab百科全书了。
- 输入demo命令,打开demo浏览,在左侧的目录中找到你关心的内容,查看其演示。从m文件到图形界面到视频动画,matlab的demo做得相当全面。
matlabcentral为全球matlab用户共享资源的地方,在那里你可以找到各个学科的很多你需要的东西,当然你也可以把自己的程序发布到那里同全球的用户共享交流:http://www.mathworks.com/matlabcentral/
关于天文方面的matlab资源,自己在网上搜罗了下面这些东西,欢迎大家补充
General Websites:
Personal/Educational Websites:
一些标准程序库:
MFITSIO:
http://public.lanl.gov/eads/mfitsio/
MFITSIO is a MATLAB interface to the cfitsio library. MFITSIO is
used to read images and headers stored in the Flexible Image
Transport System (FITS) file format. This format is most commonly
used by astrophysics to record astronomical data and observations.
【注】:
http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html
CFITSIO is a library of C and Fortran subroutines for reading and writing data files in FITS (Flexible Image Transport System) data format. CFITSIO provides simple high-level routines for reading and writing FITS files that insulate the programmer from the internal complexities of the FITS format. CFITSIO also provides many advanced features for manipulating and filtering the information in FITS files.
BY:比邻星
目录:
一、 说明
二、数据类型及基本输入输出
三、流程控制
四、循环
五、数组、数组运算和矩阵运算
六、M脚本文件和M函数文件、函数句柄
七、文件
八、数据和函数的可视化
一、说明
看了奚啸翔同学写的Fortran基本用法小结后觉得Fortran的语法既有matlab的特色也有C的
特色。于是就套用了奚啸翔同学文章的格式,写了这篇matlab基本用法小结。目的是想和
Fortran的语法有个对比,学起来更快。其实学过C、Fortran和matlab中任何一个的同学要
学其他两种语言的语法都是非常容易上手的,一天就能搞定了。有兴趣的同学还可以看看
百合Fortran版上的C、Fortran、matlab语法对比,一定能有不少收获。
此外,尽管这三种语言的语法有很多相近的地方,matlab作为数学软件有其强大的图形用
户界面操作、数据和函数的可视化和数值计算功能,且自带很多现有的函数和工具包。而
本文只涉及一些比较系统的基本操作,在最后附带介绍一些基本的数据和函数的可视化命
令。建议要用的时候再利用matlab自带的帮助文档来搜索有用的函数和工具包。matlab的
函数和命令都是比较人性化的,比如想要搜索读取fits文件的函数,搜索fits就能够搜到
fitsread函数;需要将读出的fits数据重新做图,搜索image就可以找到imagesc函数。从
书和别人的文档都只能学到有限的比较系统的操作,看帮助文档能发现更多的东西并整理
出自己的使用方法。
最后要说明的是,C必须用循环才能做到的事情Fortran和matlab用矩阵和数组运算就能做
到,相对效率提高了很多;而对于一些运算量非常大的程序还是推荐用Fortran,因为相比
之下matlab的运算速度比Fortran慢很多;而网上很多现有的天文软件包都是用fortran写
的(比如由宇宙学参数计算模拟数据的CAMB程序和宇宙模型可能性预测LIKELIHOOD程序)
,虽然matlab也有很多天文软件包,但相对fortran还是逊色不少。
二、数据类型及基本输入输出
1、数据类型,声明及赋初值
matlab中存储的数据类型(class)有以下几种:
而实际上matlab不需要对变量做声明,当它发现一个新的变量名时,将默认将其为双精度
浮点类型(double)并分配内存空间。(这比C和 Fortran方便了许多,但在完成大运算量的
程序时就显得浪费存储空间了)
当需要把变量a从double转为其他类型的时候,比如要转为int16型,可以使用以下命令:
a=int16(a)
当需要创建一个字符型变量x并对其赋初值时,用以下格式:x='字符串';
注意:
(1)在命令后加“;”表示不在command window中显示结果,而对上例来说如果不加“;”
则会显示所赋字符串内容。
(2)所有的命令必须在英文输入状态下,如果使用中文输入状态下全角的“;”,将被处
理为非法字符。
其中logical,cell和structure为逻辑,元胞和构架数组类型,将在后面的数组部分提到
;function handle为函数句柄类型,将在后面的“M脚本文件和M函数文件、函数句柄”部
分提到;java类供JAVA API应用程序接口使用,本文不进行说明。
最后说明一下,matlab也支持复数操作,赋值的时候直接输入即可,比如:a=1+2i;
2、基本输入输出
输入:v=input('message') %将用户输入的内容赋给变量v
v=input('message','s') %将用户输入的内容作为字符串赋给变量v
keyboard %用户可以从键盘输入任意多个指令
v=yesinput('prompt',default,possib)
%prompt为文字提示,default为缺省设置“值”,possib为设置值的范围。
%该指令无法在notebook中运行。
输出:disp(a)
%显示变量a的内容,另一种显示变量内容的方法是输入变量名,但是这样显示的结果带有
“a=”。
三、流程控制
1、运算符
(1)关系操作符
== ~= > >= < <=
(2)涉及相互关系的集合运算符
& | ~ xor
% xor 相异元素返回1,相同元素返回0
2、IF
(1) 基本 :
if 逻辑判断式
……
end
(2) 多重判断:
if 逻辑判断式
......
else if 逻辑判断式
......
else 逻辑判断式
......
end
end
end
3、switch-case结构
和C的switch语句一样
switch 变量
case数值1
……
case数值2
……
case 数值k %当变量等于数值k的时候,执行本组命令,然后跳出该结构。
……
otherwise
…… %该命令可以不存在,在变量不等于前面所有的检测值的时候,执行此组命
令。
end case
4、try-catch结构
try %只有当matlab执行本组命令发生错误时,后一组命令才会被执行
……
catch
…… %如果此组命令执行又出错,matlab将终止该结构。
end
%可以调用lasterr函数查询出错原因。如果函数的运行结果为一个空串,则表明这组命令
被成功执行了。
四、循环
1、while
while 表达式
……
end
2、for
for x=数值
……
……
end
%其中的数值可以是数组;或者是类似下面的表达“1:4”,表示从1到4循环;还可以是“
1:0.1:4”,表示以0.1为步长从1到4循环。
五、数组、数组运算和矩阵运算
1、 数值数组
matlab中数组不需要声明。
(1)对一维数值数组赋初值
逐个元素输入:
x=[1 2 pi/2]
冒号生成:
x=1:0.1:4
定数线性采样法:
x=linspace (a,b,n)
%相当于第一个数为a,最后一个数为b,以n为采样点数等间距采样。
x=logspace(a,b,n)
%相当于第一个数为10a,最后一个数为10b,以n为采样点数等间距采样。
(2)对一维数值数组的寻访
x(3) %寻访第三个元素
x([1 2 3]) %寻访第1,2,3个元素
x(1:3) %寻访第1到3个元素
x(3:-1:1) %由前三个元素倒排成子数组
x(find(x>0.5)) %由大于0.5的元素构成的子数组
(3)对二维数值数组赋初值
逐个赋值:
x=[1,2,3; 3,4,6; 7,8,9]
%“;”为二维数组“行”的分隔符号,而“,”和空格为同一行元素的分隔符。
整列赋值:
x(:,[4,5])=4 %第4、5列赋值为4
元素重排:
A=reshape(1:9,3,3)
%将1到9重新排列成一个(3*3)矩阵,注意matlab是列“优先”,即先排第一列再排第二
列,而不是按行来排。
(4)二维数组元素的标识和寻访
“全下标”标识:
A(3,5) %第3行第5列元素
“单下标”标识:
对于一个(m*n)维数组A中第r行第c列元素,其“单下标”表示为:A(l)
%这里l=(c-1)*m+r
2、数组运算和矩阵运算
(1)数组运算
指令
含义
A.'
相当于conj(A'),conj的作用help一下吧……
A=s
把标量s赋给A的每个元素
s+B
标量s分别与B元素之和
s-B,B-s
标量s分别与B元素之差
s.*A
标量s分别与A元素之积
s./B,B.\s
s分别被B的元素除
A.^n
A的每个元素自乘n次
A.^p
对A的各个元素分别求非整数幂
p.^A
以p为底,分别以A的元素为指数求幂
A+B
对应元素相加
A-B
对应元素相减
A.*B
对应元素相乘
A./B
A的元素被B的对应元素除
B.\A
同上
exp(A)
以e为底,分别以A的元素为指数求幂
log(A)
对A的各个元素求对数
sqrt(A)
对A的各个元素求平方根
f(A)
求A各个元素的函数值
A#B
对应元素的关系运算,#代表关系运算符
A@B
对应元素的逻辑运算,@代表逻辑运算符
(2)矩阵运算
指令
含义
A'
共轭转置
s*A
标量s分别与A元素之积
S*inv(B)
B阵的逆乘s
A^n
A阵为方阵时,自乘n次
A^p
方阵A的非整数乘方
p^A
A阵为方阵时,标量的矩阵乘方
A+B
矩阵相加
A-B
矩阵相减
A*B
矩阵相乘
A/B
A右除B
B\A
A左除B
expm(A)
A的矩阵指数函数
logm(A)
A的矩阵对数函数
sqrtm(A)
A的矩阵平方根函数
funm(A,'FN')
一般矩阵函数
3、逻辑数组
看例子就明白了:
A=zeros(2,5); %预生成一个(2*5)全零数组
A(:)=-4:5; %运用“全元素”方法向A赋值
L=abs(A)>3 %产生一个与A同维的“0 -1”逻辑值数组
islogical(L) %判断L是否逻辑值数组。输出若为1,则是
X=A(L) %把L中逻辑值为1对应的A元素取出
4、字符串数组
(1)字符串数组赋初值
S=['aa'
'bb']
或者:
S=char('aa','bb')
还可以:
S=str2mat('aa',' ','bb') %这里空串会产生空行
而:
S=str2cat('aa',' ','bb') %这里空串不会产生空行
(2) 字符串操作函数
int2str %把整数数组转换为串数组
num2str %把非整数数组转换为串数组
mat2str %把数值数组转换为串数组
%请使用help搜索其他的字符串操作函数。
5、元胞数组
元胞数组和一般数值数组和字符串数组不同,其元素可以是任意类型和大小的对象。这
和C的结构型数组有些类似。
(1)创建元胞数组
有以下两种创建方式:
外标识元素赋值:
a=char('aa' 'bb');
b=1:9;
c=2:5;
d=[1+2i];
A(1,1)={a}; A(1,2)={b}; A(2,1)={c}; A(2,2)={d};
内涵的直接赋值:
a=char('aa' 'bb');
b=1:9;
c=2:5;
d=[1+2i];
A{1,1}=a; A{1,2}=b; A{2,1}=c; A{2,2}=d;
(2)元胞数组内容的调取
注意在这里()访问的是元胞,用{}访问的是元胞中存储的内容。
比如:a=A(1,1)
显示:
a=
[12 char]
而:a=A{1,1}
显示:
a=
aa
bb
所以用{}而不是()调取元胞数组内容。
6、构架数组
构架数组和元胞数组类似,但其每个构架(地位相当于元胞数组的元胞)必须划分“域”
后才能使用。看下面的例子:
green_house(2,3).name='六号房';
green_house(2,3).param.temperature=30;
green_house(2,3).param.humidity=10;
green_house
屏幕显示:
23 struct array with fields:
name
param
注意:
(1)在一个构架上进行的增减域的操作会影响到整个数组。
(2)增减子域不会影响到其他构架。
7、空数组
(1)有下面几种产生空数组的方法:
a=[]
b=ones(2,0) %ones的作用原本是产生一个全1的数组
c=zeros(2,0) %zeros的作用原本是产生一个全0的数组
d=eye(2,0) %eye的作用原本是产生一个对角元全为1的数组
f=rand(2,3,0,4) %rand的作用原本是产生随即数组。
(2)空数组可用于子数组的删除和数组大小的收缩
A(:,2)=[]
六、M脚本文件和M函数文件、函数句柄
m文件分两种:函数和脚本。
1、matlab script file:
脚本文件没有输入输出,对工作空间(workspace)中的变量进行操作。
任何可执行的matlab命令都可以写入脚本文件。先来看一个简单的例子:
例1: 产生一个20元素的一维随机数组并画出。
解: 新建一个m文件命名为randplt.m(或者任何你喜欢的名字), 在其中加入如下两行代码
:
data=randn(1,20);
plot(data);
保存后选择debug/run菜单或按F5键运行,观察workspace中多出了一个变量data。
脚本文件执行时, 就如同将文件中的每一条命令依次输入到matlab命令行中一样, 顺次执
行。你可以尝试在command history窗口中按住ctrl键选择几行执行过的命令并单击鼠标右
键在快捷菜单中选择creat M file来快速创建一个m文件。
2、matlab function
函数文件可以接受输入和给出输出,当然也可以没有,就像c语言的函数。matlab函数最大的
书写特点(同C比起来)是它的输出变量定义在函数名前面。看一例:
例2: matlab内部函数std给出数组的标准差std=sqrt(sum(X)/N),编写函数stderr求实验误
差err=sqrt(sum(X)/(N*(N-1))), 代码如下:
function err=stderr(arr)
%实验误差(标准差估计)
%caculate along each column of arr
err=std(arr)./sqrt(size(arr,1)-1);
文件存为stderr.m, 运行时输入a=[1;2;3];建立一个列数组a, 然后输入stderr(a)则给出
a的方差。(若输入行数组则发散,因N-1=0)
此例中输入变量为arr, 函数名为stderr, 输出变量err, 此三者皆写在关键字function后
面同一行。无需再使用return将err的值返回。
注意:
(1)函数文件的命名要使用文件内主函数声明的名称,否则出错。
(2)函数内部可以嵌套子函数并为该文件的主函数调用,只需将子函数写在主函数代码后
面。
(3)一个函数可以有多个输入输出。如function [y1,y2]=myfun(x1,x2,x3)
例1中的m文件可在第一行前插入一行:
function randplt
保存后则该文件成为一个没有输入输出宗量的函数。
一般来说matlab中执行同样的任务使用函数文件比脚本文件的效率高。
3.函数句柄的使用
函数句柄起到c语言中函数指针的作用。
例3: 编写函数求出数组arr1和arr2的标准差(std)以及误差(stderr)。
解: 编写如下文件并保存为erreval.m
function [s1,s2]=erreval(err,arr1,arr2)
% err为所调用的误差函数,s1,s2分别返回arr1和arr2的误差.
s1=feval(err,arr1);
s2=feval(err,arr2);
此文件的输入包含"函数变量", 通过函数句柄实现函数变量err的赋值。
运行时先运行如下命令建立数组arr1,arr2:
arr1=[1;2;3];
arr2=[10;20;30];
然后输入
[std1,std2]=erreval(@std,arr1,arr2)
[stderr1,stderr2]=erreval(@stderr,arr1,arr2)
执行后返回四个误差值。
@std,@stderr为两误差函数的函数句柄。
七、文件
打开文件:
fid = fopen(filename,permission)
%其中的permission为打开类型,具体可查阅matlab的帮助文档。
读文件:
[A,count] = fread(fid,size,precision)
%A 为存放读入数据的变量。
%count 为可选参数,存放成功读取的数据个数。
%fid 为文件指针。
%size 为要求读入的数据量大小,缺省状态下读到文件末尾。
%presision 为读出数据格式。
写文件:
count = fwrite(fid,A,precision)
八、数据和函数的可视化
图像的精细控制大有文章可做,这里只介绍一些做图最常用的基本命令。
1.二维数据的可视化
设x,y为两等长的一维数组,若要将x,y对应位置的元素做图,可使用以下命令:
plot(x,y);
如果使用:
plot(x);
就相当于:
s=size(x);
plot(x,[1:s(2)]);
我们可以对线型和色彩做控制,比如plot(x,y,'.r')画出的是红色点线。
线型和色彩控制值如下表:
| 符号 | 线型 |
| - | 实线 |
| : | 虚线 |
| -. | 点划线 |
| -- | 双划线 |
| 符号 | 颜色 |
| b | 蓝 |
| g | 绿 |
| r | 红 |
| c | 青 |
| m | 品红 |
| y | 黄 |
| k | 黑 |
| w | 白 |
2.三维数据的可视化
plot3最容易理解:
plot3(X,Y,Z);
另外的两个基本命令是:
mesh(X,Y,Z) %画网线图。
mesh(Z) %以Z矩阵列行下标为x,y轴自变量画网线图。
surf(X,Y,Z) %画曲面图。
surf(Z) %以Z矩阵列行下标为x,y轴自变量画曲面图。
3.图像控制命令
figure %打开新的作图窗口
axis([0,pi,-1,1]) %控制坐标轴的范围
title('pic') %为图像增加标题
grid on %显示坐标网格
legend %显示图例
hold on %在画下一幅图的时候,保留之前的图。
hold off %停止保留之前的图。
colorbar %显示颜色条
box on %显示三维图的长方体边框
%全文结束。
相关文章:
待添加
待添加
宾夕法尼亚大学统计天文学中心维护的天文学和物理学科数据统计相关的代码列表,涵盖内容及其广泛,并且提供相关的教程、文献选录以及可供练习的部分实测数据。
此外该中心每年6月份还会举办天文学中统计方法的暑期学校。
![]()
StatCodes is a Web metasite with links to public domain software implementing statistical methods. The
codes are chosen for their potential utility for research in astronomy and other physical sciences. Some are obtained from large code archives (such as R, CRAN, StatLib, GAMS), while others are scattered throughout the Internet. It includes multi-purpose statistical computing systems, single-purpose packages, single-purpose source codes,and various Web resources and services. StatCodes listings are organized by statistical topic.
In mid-2005, StatCodes was updated and incorporated into Penn State's Center for Astrostatistics (CASt).
CASt provides a range of statistical resources for the physical scientist including astrostatistical tutorials, annotated bibliographies, conferences and research in addition to StatCodes.
![]()