⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mf_findexternal.hlp

📁 是一个经济学管理应用软件 很难找的 但是经济学学生又必须用到
💻 HLP
字号:
{smcl}
{* 16mar2005}{...}
{cmd:help mata findexternal()}
{hline}
{* index pointers}{...}
{* index externals}{...}
{* index global variable}{...}
{* index findexternal}{...}
{* index crexternal}{...}
{* index rmexternal}{...}

{title:Title}

{p 4 4 2}
{bf:[M-5] findexternal() -- Find, create, and remove external globals}


{title:Syntax}

{p 8 12 2}
{it:pointer()}
{it:scalar} 
{cmd:findexternal(}{it:string scalar name}{cmd:)}

{p 8 12 2}
{it:pointer()}
{it:scalar} 
{cmd:crexternal(}{it:string scalar name}{cmd:)}

{p 8 12 2}
{it:void}{bind:             }{cmd:rmexternal(}{it:string scalar name}{cmd:)}


{title:Description}

{p 4 4 2}
{cmd:findexternal(}{it:name}{cmd:)}
returns a pointer (see {bf:{help m2_pointers:[m-2] pointers}}) 
to the external global 
matrix, vector, or scalar whose name is specified by {it:name}; it returns
NULL if the external global is not found.

{p 4 4 2}
{cmd:crexternal(}{it:name}{cmd:)}
creates a new external global 0{it:x}0 real matrix with the 
specified name and returns a pointer to it; it returns NULL if an 
external global of that name already exists.

{p 4 4 2} 
{cmd:rmexternal(}{it:name}{cmd:)}
removes (deletes) the specified external global or does nothing if 
no such external global exists.


{title:Remarks}

{p 4 4 2}
Remarks are presented under the headings

	{bf:Definition of a global}
	{bf:Use of globals}

{p 4 4 2}
Also see {it:Linking to external globals} in 
{bf:{help m2_declarations:[M-2] declarations}}.


{title:Definition of a global}

{p 4 4 2}
When you use Mata interactively, any variables you create are known,
equivalently, as externals, globals, or external globals.

	: {cmd:myvar = x}

{p 4 4 2}
Such variables can be used by subsequent functions that you run, and 
there are two ways that can happen:

	{cmd:function example1(...)}
	{cmd:{c -(}}
		{cmd:external real myvar}

		... {cmd:myvar} ...
	{cmd:{c )-}}

{p 4 4 2}
and 

	{cmd:function example2(...)}
	{cmd:{c -(}}
		{cmd:pointer(real) p}

		{cmd:p = findexternal("myvar")}
		... {cmd:*p} ...
	{cmd:{c )-}}

{p 4 4 2}
Using the first method, you must know the name of the global at the time you
write the source code, and when you run your program, if the global does not
exist, it will refuse to run (abort with {cmd:myvar} not found).  Using the
second method, the name of the global can be specified at run time and what is
to happen when the global is not found is up to you.

{p 4 4 2}
In the second example, although we declared {cmd:p} as a pointer to a 
real, {cmd:myvar} will not be required to contain a real.  After 
{cmd:p} {cmd:=} {cmd:findexternal("myvar")}, if {cmd:p!=NULL}, 
{cmd:p} will point to whatever {cmd:myvar} contains, whether it 
be real, complex, string, or another pointer.  (You can diagnose 
the contents of {cmd:*p} using {bf:{help mf_eltype:eltype(*p)}} and 
{bf:{help mf_eltype:orgtype(*p)}}.)


{title:Use of globals}

{p 4 4 2}
Globals are useful when a function must remember something from one 
call to the next:

	{cmd}function example3(real scalar x)
	{
		pointer() scalar p 

		if ( (p = findexternal("myprivatevar")) == NULL) {
			printf("you haven't called me previously")
			p = crexternal("myprivatevar")
		}
		else {
			printf("last time, you said "%g", *p)
		}
		*p = x 
	}{txt}

	: {cmd:example3(2)}
	you haven't called me previously

	: {cmd:example3(31)}
	last time, you said 2

	: {cmd:example3(9)}
	last time, you said 31

{p 4 4 2}
Note our use of the name {cmd:myprivatevar}.  It actually is not 
a private variable; it is global, and you would see the variable listed 
if you described the contents of Mata's memory.  Because global variables 
are so exposed, it is best that you give them long and unlikely names.

{p 4 4 2}
In general programs do not need global variables.  The exception is 
when a program must remember something from one invocation to the next, 
and especially if that something must be remembered from one invocation 
of Mata to the next.

{p 4 4 2}
When you do need globals, you probably will have more than one thing you will
need to recall.  There are two ways to proceed.  One way is simply to 
create separate global variables for each thing you need to remember.  
The other way is to create a single global pointer vector and store 
everything in that.  In the following example, we remember one scalar 
and one matrix:

	{cmd}function example4()
	{
		pointer(pointer() vector) scalar   p 
		scalar                             s
		real matrix                        X
		pointer() scalar                   ps, pX

		if ( (p = findexternal("mycollection")) == NULL) {
			... {txt:{it:calculate scalar s and X from nothing}} ...
			... {txt:{it:and save them:}}
			p = crexternal("mycollection")
			*p = (&s, &X)
		}
		else {
			ps = (*p)[1]
			pX = (*p)[2] 
			... {txt:{it:calculate using *ps and *pX}} ...
		}
	}{txt}

{p 4 4 2}
In the above example, note that even though {cmd:crexternal()} created a
0{it:x}0 real global, we morphed it into a 1{it:x}2 pointer vector:

			{cmd:p = crexternal("mycollection")}     *p is 0x0 real
			{cmd:*p = (&s, &X)}                      *p is 1x2 vector

{p 4 4 2}
just as we could with any nonpointer object.

{p 4 4 2}
In the else-part of our program, where we use the previous values, 
we do not use variables {cmd:s} and {cmd:X}, but {cmd:ps} and {cmd:pX}.
Actually, we did not really need them, we could just as well have used
{cmd:*((*p)[1])} and {cmd:*((*p)[2])}, but 
the code is more easily understood by introducing 
{cmd:*ps} and {cmd:*pX}.

{p 4 4 2}
Actually, we could have used the variables {cmd:s} and {cmd:X} by changing 
the else-part of our program to read

		{cmd}else {
			s = *(*p)[1]
			X = *(*p)[2] 
			... {txt:{it:calculate using s and X}} ...
			*p = (&s, &X)         <- remember to put them back
		}{txt}

{p 4 4 2}
Doing that is inefficient because {cmd:s} and {cmd:X} contain copies of 
the global values.  Obviously, the amount of inefficiency depends on 
the sizes of the elements being copied.  In the case of {cmd:s}, there 
is really no inefficiency at all because {cmd:s} is just a scalar.  In the 
case of {cmd:X}, the amount of inefficiency depends on the dimensions 
of {cmd:X}.  Making a copy of a small {cmd:X} matrix would introduce 
just a little inefficiency.

{p 4 4 2} 
The best balance between efficiency and readability is achieved by 
introducing a subroutine:

	{cmd}function example5()
	{
		pointer(pointer() vector) scalar   p 
		scalar                             s
		real matrix                        X

		if ( (p = findexternal("mycollection")) == NULL) {
			example5_sub(1, s=., X=J(0,0,.))
			p = crexternal("mycollection")
			*p = (&s, &X)
		}
		else {
			example5_sub(0, (*p)[1], (*p)[2])
		}
	}

	function example5_sub(scalar firstcall, scalar x, matrix X)
	{
		...
	}{txt}

{p 4 4 2}
Note that the last two lines in the not-found case

			{cmd}p = crexternal("mycollection")
			*p = (&s, &X){txt}

{p 4 4 2}
could also be coded

			{cmd:*crexternal("mycollection") = (&s, &X)}


{title:Diagnostics}

{p 4 4 2}
{cmd:findexternal(}{it:name}{cmd:)}, 
{cmd:crexternal(}{it:name}{cmd:)}, and 
{cmd:rmexternal(}{it:name}{cmd:)}
abort with error if {it:name} contains an invalid name.

{p 4 4 2}
{cmd:findexternal(}{it:name}{cmd:)} returns NULL if {it:name} does not exist.

{p 4 4 2}
{cmd:crexternal(}{it:name}{cmd:)} returns NULL if {it:name} already exists.


{title:Source code}

{p 4 4 2}
Functions are built-in.


{title:Also see}

{p 4 13 2}
Manual:  {hi:[M-5] findexternal()}

{p 4 13 2}
Online:  help for 
{bf:{help mf_valofexternal:[M-5] valofexternal()}};
{bf:{help m4_programming:[M-4] programming}}
{p_end}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -