—颂卖—————
补充一下:在较新的版本中(具体哪版开始的我不记得了),可以使用
GeneralUtilities`PrintDefinitions
函数来查看部分内置函野敬逗数的源代码,但是,能够看的依旧只有稿槐少数直接用Mathematica写成的函数。
可以调用C语言的方法,如下1.用C语言写脊宏旁好函数,如
double f(double x,double y){
return x*y
}
2.找到路径,比如C:\Program Files\Wolfram Research\Mathematica\6.0
\SystemFiles\Links\MathLink\DeveloperKit\Windows\MathLinkExamples\addtwo或相应安装目录下的addtwo.c以及
addtwo.tm两个文件拷贝到某个自己的文件夹中。
3.将addtwo.c以及addtwo.tm依照用C语言写好的函数进行修改存为f.c以及f.tm,其中本例需要修改之处
(1)addtwo.c中"extern int addtwo( int i, int j)"及以下函数addtwo代码部分替换为函数f相应的代码。
(2)addtwo.tm中Function、Pattern、Arguments、ArgumentTypes、ReturnType均需要按照f的定义进行修改,其中
addtwo两个变量均是int返回值也是int而f的变量和返回值均为double,故应当将其中Integer相应改为Real
(3)如果需要用户能在Mathematica中通过?+函数名来查询函数功能,则需修改:Evaluate:项中相应的内容
特别注意(至少)若安装有Visual Studio 6则不可按文档
Tutorial/SettingUpExternalFunctionsToBeCalledFromMathematica中所述的方法自行编写f.c,那样会导致LINK时提
示WinMain函数无定义
4.安装负责将MathLink template文件生成C代码的mprep.exe,做法如下
(1)进入C:\Program Files\Wolfram Research\Mathematica\6.0
\SystemFiles\Links\MathLink\DeveloperKit\Windows\CompilerAdditions\MLDev32或非默认安装位置的相应文件夹
(2)按下Ctrl键,选中并拖拽Lib,Include,Bin三个文绝告件夹进入路径C:\Program Files\Microsoft Visual Studio\VC98
(Visual Studio 6)或C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK(Visual Studio 2005)或任何非
默认安装路径相应文件夹下
(3)出现提示对话框时选择"是"或"全部"
此 *** 作会将Mathematica的三个文件夹中的文件复制到VC同名文件夹下
4.完成后进入命令行并进入存储f.c以及f.tm的文件夹,输入如下语句
SET CL=/nologo /c /DWIN32 /D_WINDOWS /W3 /O2 /DNDEBUG
SET LINK=/NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no /PDB:NONE kernel32.lib user32.lib gdi32.lib
MPREP f.tm -o ftm.c
CL f.c ftm.c
LINK f.obj ftm.obj ml32i3m.lib /OUT:f.exe
此 *** 作最终将会编译出可被Mathematica调用的MathLink程序f.exe
其中前两句将(创建及)改变环境变量CL,LINK的值,其选项的意义详见Mathematica文档
tutorial/MathLinkDeveloperGuide-Windows
mprep句执行后应生成ftm.c,-o意为输出成文件,CL句执行后将生成f.obj以及ftm.obj,LINK句将生成f.exe,其中
ml32i3m.lib为MathLink所需的库文件,应当位于编译器所能找到的路径中
5.在Mathematica中安装并调用程序。可用如下语句调入程序
link=Install["[路樱橡径]\\f"]
其中[路径]应用f.exe所在路径代替。卸载程序时只需用语句
Uninstall[link]
即可
……上面那个答案明明什搜纳么都没说,为什么你采纳了啊?
算了不管了,总之这里是我的答案。这个问题的关键在于DiracDelta的处理。DiracDelta可以做近似处理,比如说使用:
eq = With[{n = n[t, x]}, D[n, t] == D[n, x, x]]
bc = {n[t, 0] == 0, D[n[t, x], x] == 0 /. x ->1}
dirac[r_, a_] := Sqrt[a/Pi] Exp[-a r^2]
ic = n[0, x] == 2 n0 dirac[x - 1, 100](*注意这个 2 是必要的,因为你的DiracDelta设在了端点上*)
nsol = NDSolveValue[{eq, ic, bc} /. n0 ->1, n, {t, 0, 1/10}, {x, 0, 1}]
np = Plot3D[nsol[t, x], {t, 0, 1/10}, {x, 0, 1}, PlotRange ->All, PlotStyle ->Red]
效果就已经不错了。
不过,对于你这个问题,还存在更准确的处理方桥橡法,因为它的解析解是可求的,只要用上LaplaceTransform:
eq = With[{n = n[t, x]}, D[n, t] == D[n, x, x]]
bc = {n[t, 0] == 0, D[n[t, x], x] == 0 /. x ->1}
ic = n[0, x] == n0 DiracDelta[x - 1]
teqn =
LaplaceTransform[{eq, bc}, t, s] /. Rule @@ ic /.
HoldPattern@LaplaceTransform[a_, __] :>a /. n ->(n@#2 &)
(* {-n0 DiracDelta[-1 + x] + s n[x] == (n^′′)[x], {n[0] == 0,
Derivative[1][n][1] == 0}} *)
tsol = n[x] /. First@DSolve[teqn, n[x], x]
(* (1/(2 (1 + E^(2 Sqrt[s])) Sqrt[s]))E^(-Sqrt[s] -
Sqrt[s] x) n0 (-2 E^(2 Sqrt[s]) + 2 E^(2 Sqrt[s] + 2 Sqrt[s] x) +
E^(2 Sqrt[s]) HeavisideTheta[-1 + x] + E^(4 Sqrt[s]) HeavisideTheta[-1 + x] -
E^(2 Sqrt[s] x) HeavisideTheta[-1 + x] -
E^(2 Sqrt[s] + 2 Sqrt[s] x) HeavisideTheta[-1 + x]) *)
tsol 是经过了拉普拉斯变换的这个问题的解析解,最后一步就是倒回去了,不过呢它的符号求解似乎不可能,于是我们如果要数值解的话,就需要数值拉普世消没拉斯反变换。这里我将使用这个程序包:library.wolfram.com/infocenter/MathSource/5026
这里以n0等于1为例:
tsolfunc = Function[{s, x}, #] &[tsol /. n0 ->1]
(*注意FT要从上面的程序包里调出来。*)
solgenerator[t_] :=
solgenerator[t] = Module[{x}, Compile[#, #2] &@@ {x, FT[tsolfunc[#, x] &, t]}]
Plot3D[solgenerator[t][x], {t, 0, 1/10}, {x, 0, 1}, PlotRange ->All]
最后,这个帖子里是个类似的问题。其中有一些针对DiracDelta的更详细说明,有兴趣可以读读:http://tieba.baidu.com/p/4126799131
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)