2011年11月24日星期四
2011年11月10日星期四
Makefile Tutorial
'via Blog this'
Well, I have news for you... Your days of command line compiling are (mostly) over, because YOU will learn how to write Makefiles.
Makefiles are special format files that together with the make utility will help you to automagically build and manage your projects.
For this session you will need these files:
note: I use g++ for compiling. You are free to change it to a compiler of your choice
The make utility
If you runmakethis program will look for a file named makefile in your directory, and then execute it.
If you have several makefiles, then you can execute them with the command:
make -f MyMakefileThere are several other switches to the
make utility. For more info, man make.Build Process
- Compiler takes the source files and outputs object files
- Linker takes the object files and creates an executable
Compiling by hand
The trivial way to compile the files and obtain an executable, is by running the command:g++ main.cpp hello.cpp factorial.cpp -o hello
The basic Makefile
The basic makefile is composed of:target: dependencies [tab] system commandThis syntax applied to our example would look like:
all: g++ main.cpp hello.cpp factorial.cpp -o hello[Download here]
To run this makefile on your files, type:
make -f Makefile-1On this first example we see that our target is called all. This is the default target for makefiles. The make utility will execute this target if no other one is specified.
We also see that there are no dependencies for target all, so make safely executes the system commands specified.
Finally, make compiles the program according to the command line we gave it.
Using dependencies
Sometimes is useful to use different targets. This is because if you modify a single file in your project, you don't have to recompile everything, only what you modified.Here is an example:
all: hello hello: main.o factorial.o hello.o g++ main.o factorial.o hello.o -o hello main.o: main.cpp g++ -c main.cpp factorial.o: factorial.cpp g++ -c factorial.cpp hello.o: hello.cpp g++ -c hello.cpp clean: rm -rf *o hello
Download here]Now we see that the target all has only dependencies, but no system commands. In order for make to execute correctly, it has to meet all the dependencies of the called target (in this case all).
Each of the dependencies are searched through all the targets available and executed if found.
In this example we see a target called clean. It is useful to have such target if you want to have a fast way to get rid of all the object files and executables.
Using variables and comments
You can also use variables when writing Makefiles. It comes in handy in situations where you want to change the compiler, or the compiler options.# I am a comment, and I want to say that the variable CC will be # the compiler to use. CC=g++ # Hey!, I am comment number 2. I want to say that CFLAGS will be the # options I'll pass to the compiler. CFLAGS=-c -Wall all: hello hello: main.o factorial.o hello.o $(CC) main.o factorial.o hello.o -o hello main.o: main.cpp $(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp $(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp $(CC) $(CFLAGS) hello.cpp clean: rm -rf *o hello[Download here]
As you can see, variables can be very useful sometimes. To use them, just assign a value to a variable before you start to write your targets. After that, you can just use them with the dereference operator $(VAR).
Where to go from here
With this brief introduction to Makefiles, you can create some very sophisticated mechanism for compiling your projects. However, this is just a tip of the iceberg. I don't expect anyone to fully understand the example presented below without having consulted some Make documentation (which I had to do myself) or read pages 347 to 354 of your Unix book.CC=g++ CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@[Download here]
If you understand this last example, you could adapt it to your own personal projects changing only 2 lines, no matter how many additional files you have !!!.
Makefiles
Makefiles
by example
| Compiling your source code files can be tedious, specially when you want to include several source files and have to type the compiling command everytime you want to do it. Well, I have news for you... Your days of command line compiling are (mostly) over, because YOU will learn how to write Makefiles. Makefiles are special format files that together with the make utility will help you to automagically build and manage your projects. For this session you will need these files: note: I use g++ for compiling. You are free to change it to a compiler of your choice The make utilityIf you runmakethis program will look for a file named makefile in your directory, and then execute it. If you have several makefiles, then you can execute them with the command: make -f MyMakefileThere are several other switches to the make utility. For more info, man make.Build Process
Compiling by handThe trivial way to compile the files and obtain an executable, is by running the command:g++ main.cpp hello.cpp factorial.cpp -o hello The basic MakefileThe basic makefile is composed of:target: dependencies [tab] system commandThis syntax applied to our example would look like: To run this makefile on your files, type: make -f Makefile-1On this first example we see that our target is called all. This is the default target for makefiles. The make utility will execute this target if no other one is specified. We also see that there are no dependencies for target all, so make safely executes the system commands specified. Finally, make compiles the program according to the command line we gave it. Using dependenciesSometimes is useful to use different targets. This is because if you modify a single file in your project, you don't have to recompile everything, only what you modified.Here is an example: all: hello hello: main.o factorial.o hello.o g++ main.o factorial.o hello.o -o hello main.o: main.cpp g++ -c main.cpp factorial.o: factorial.cpp g++ -c factorial.cpp hello.o: hello.cpp g++ -c hello.cpp clean: rm -rf *o hello Download here]Now we see that the target all has only dependencies, but no system commands. In order for make to execute correctly, it has to meet all the dependencies of the called target (in this case all). Using variables and commentsYou can also use variables when writing Makefiles. It comes in handy in situations where you want to change the compiler, or the compiler options.# I am a comment, and I want to say that the variable CC will be # the compiler to use. CC=g++ # Hey!, I am comment number 2. I want to say that CFLAGS will be the # options I'll pass to the compiler. CFLAGS=-c -Wall all: hello hello: main.o factorial.o hello.o $(CC) main.o factorial.o hello.o -o hello main.o: main.cpp $(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp $(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp $(CC) $(CFLAGS) hello.cpp clean: rm -rf *o hello[Download here]As you can see, variables can be very useful sometimes. To use them, just assign a value to a variable before you start to write your targets. After that, you can just use them with the dereference operator $(VAR). Where to go from hereWith this brief introduction to Makefiles, you can create some very sophisticated mechanism for compiling your projects. However, this is just a tip of the iceberg. I don't expect anyone to fully understand the example presented below without having consulted some Make documentation (which I had to do myself) or read pages 347 to 354 of your Unix book.CC=g++ CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@[Download here] If you understand this last example, you could adapt it to your own personal projects changing only 2 lines, no matter how many additional files you have !!!. |
2011年10月17日星期一
椭圆运动的研究
'via Blog this
行星运动
许剑伟 2006-1-9
一、极坐标问题
横向速度:;径向速度:
。式中r为标量。
加速度分析:考相近两点的速度:
将第2点的速度分解到第1点速度的横向和径向上得:
则
取极限(不计二阶小量时)有:
同理:
二、力学方程:
国际单位制中,万有引力常数G的值精度不够,要得到5有效数字的精密G值已经很困难,另外我们所知道的以千克为单位的天体质量精度也很差,而天文观测数据的精度高达8—10位有效数字,所以使用国际单位制的力学方程不能直接用于天体计算,须重新定义单位:
定义M=1个单位(该单位的名称由计算者自已定,如使用太阳质量为一个单位)r=1个单位(如天文长度单位之类的名称)时,a的值为1个单位,那么可得k=1。
这样就得到
牛顿第二定律成立条件离不开牛顿第一定律。牛顿第一定律讲到:物体不受外力时,物体保持静止或匀速直线运动,受外力时则加速(或减速)运动。牛顿第二定律把这种加速或减速运动数量化,从数学上看,数量化过程依赖一定的坐标系统,从F=ma看到,当f=0时,a=0,而从实际的实验来看,f=0时a不一定等于零,与选定的坐标有关,当选定的坐标系统满足牛顿第一定律时(惯性系)才有f=0,a=0,这时牛顿第二定律才会有很高的精度。总之,利用牛一定律确定惯性系后,牛二定律才是正确的(或者说是高精度的)。假如我们找到一个坐标系统A使得物体运动满足牛一定律,如果另一个坐标系B相对A匀速运动,那么B坐标也是惯性坐标系。所有的行星、太阳之间都有相互引力,都相对于惯性系做加速运动,而不是匀速运动,以任意一个行星作为参考系都不是惯性系。那么在非惯性系中如何描述物体运动呢?从以上分析得知,在非惯性系中f=0时a≠0,因此计算时必需对a进行修正,修正方法是:如果非惯性系B相对惯性系A的加速度为a0,那么在B中描述物体加速度a时,应修正为a-a0。这里不再作证明,读者可以从运动的相对性出发加以理解、证明。当以某一天体为坐标中心,用该坐标描述其它天体运动的加速度时,应通通减去坐标中心天体的加速度。不管以太阳为中心还是以地求为中心,都须做此修正。因此无所谓太阳中心说还是地球中心说,不管用哪个学说均能得到正确结果,对于数值计算而言只是坐标的选择、变换及精度问题。
作加速度修正的结果就是,中心天体的有效质量变为所有天体的质量总和,证明过程比较简单,这里不再赘述。
设二体质量之和为M=m1+m2,二体距离为r。
对第二式积分易得,表示角动量守恒,代入第一式时行变换
,这是一个二阶常微分方程,解的形式是
三、关于椭圆
(一) 椭圆的定义
椭圆性质1:有两个焦点,左右各一个,对称。椭圆上点到两焦点距之和总为长轴。
椭圆性质2:椭圆可由圆在平面上影射得到。圆与平面夹角为,e为离心率。
1、椭圆极坐标方程:
2、近点:;远点:
3、半长径(根数):
4、椭圆中心到焦点距离:
5、椭圆通径(半短轴长度):即求的最大值
;用导数法易求得
6、离心律(根数):(定义)
(二)能量、动量守恒定律
势函数:;动能:
;横向动能:
;径向动能:
能量守恒:;或者:
;注意,C是负数。
角动量守恒方程:;或者:
角动量的能量形式表达:
(三)A、B的能量表达式
(四)轨道根数的能量表达式
将A、B代入椭圆方程得:
(五)轨道根数的反算:
(六)轨道的周期:
1、偏近点角与真近点角的关系
(1)偏近点角指与近点角对应的做椭圆影射的那个正圆上的圆心角
左右两边用正切半角公式代换易得
(2)偏近点角与真近点角的偏导关系
(3)偏近点角与e的偏导关系:
2、开普勒周期的导出
将
显然,当角度转一周后得周期:,即开普勒第三定律(周期定律),太阳系中,所有行星周期只与半径有关,或周期只与能量有关
3、估计轨道近点可能需要的计算:
以下的计算可用于行星之间相互引力摄动作用时的初始轨道修正。
有初始近点角时
设,偏导关系如下
此偏导将用于初始状态计算
五、球面坐标系统
1、球面三角计算:
下图以黄经纬、赤经纬为例作图。
A为黄极(一个顶点),B为北极(第二个顶点),C为某一个天体(第三个顶点),接下来逐步讨论黄道坐标与赤道坐标的关系。
方法:转到直角坐标,用直角坐标中的二点间距离公式求角BC弦长,进而求得角度。直角坐标x轴为OJ,y轴为OA,z轴向前,则B、C坐标为。
代入距离公式得到球面三角关系式
如果已知AB弧和BC弧和夹角,求AC弧。通过轮换的方法得
纬度有正负,经度也可规定正负,但弧的球心角只有正值,不能为负,就象三角形的边长不能为负一样。
2、经度与纬度
图中红色粗线表示黄经HJ和黄纬W,黑色粗线表示赤经J和赤纬W
夹角取正也可取负,不影球面三角关系等式。取正C点在AB的右边,取负C点在AB的左。
经度以升分点开始计算,夹角以升分点过后90度起算。则有
。
现在考虑黄经(HW)黄纬(HW)与赤经(J)赤纬(W)的关系。太阳过春分点,即升分点,此点为黄经起算坐标,则有。对于赤经来说,它的升分点与黄经相差180度,为了坐标统一,如果赤经以黄经的起点开始计算,则
。纬度与球面三角的角度关系为
。代入球面三角得:
用反正弦求出的经度在-90度到90度之间,应转换到0-360度。这个问题实际上是已知正弦值求角。如果正弦值为正,则在第一象限和第二象限也有一个解,要取哪一个,则由已知经角的象限决定。黄经和赤经是在同一象限的。
如要赤道坐标与黄道坐轮换,并将黄赤交角取负值,方程式不变,
这样正求角与反求角的方程形式完全一样。如虽你按上述方程设计了一个函数求解W和J,入口参数为HW、HJ和交角,(或者这个函数求的是HW、HJ,入口参数为W,J)有了这个函数可反求,只需轮换并交角取负。
六、牛顿内插公式
。
一阶差分:
二阶差分:
k阶差分:
建立差分表:
考查的点有N+1个,过这N+1个点的多项式可表示为一个N阶差分的多项式:
我们可用多项式F(x)来逼近f(x)。本文不打算推导这个公式,详阅牛顿内插法相关的著作。。
N点确定的多项式是唯一的,最笨方法通过待定系数法求多项式的系数,N+1个方程求N+1个系数,如果没有出现某些奇异问题,系数解是唯一的。
现在外推一步。即。
外推后有
这是平移过程,平移后是同一个函数,因为它们过相同的N个点,如果用待定系数法求解,系数相同。
直接求计算量比较大。N阶多项式可表示为作N+1阶的多项,只要N+1差分置0,就可使多项式不变,然后通过差分表反推,可得
。如果依此类推
等等,最后可将差分表推算为一个矩形表。矩形表中的每行都可应用插值多项式逼近f(x),每行的插多项式为同一函数。
对f(x)的定积分:用逼近多项式F(x)积分代替f(x)的积分,进而求得v(x)。因每行都有一个积分表达式,而且算式统一,使用程序简化且效率提高。有多种积分选择,建议如下:
为了提高运算效率,使用以下算式计算
七、牛顿中心差分公式
设,
1、奇数点插值公式(牛顿-斯特林公式):
偶数点插值公式(也称为牛顿-贝塞尔插值公式):
2、节点是
八、高斯插值公式:
1、高斯向前插值:
2、高斯向后插值:
九、牛顿—贝塞尔插值:
可由高斯向前插值导出。从形式上看,高斯插值的偶数阶δ的下脚标为0,我们可以转换为下地脚标为1/2的形式。当然差分表中没有下脚标为1/2的偶数阶δ,以下将会重新定义。
以下导出第2m项和第2m+1项
这样易得《2008中国天文年历》中的贝塞尔插公式。
如果用x+1/2代x,将得前面所述的牛顿—贝塞尔公式(x从1/2处起算)
