Maxima:定义一个函数,该函数 returns 一个范围内的随机整数,使得该值不同于另一个值或其他值的列表
Maxima: define a function that returns a random integer in a range, such that the value is distinct from another value or a list of other values
N.B. 标题中的问题在下面的“编辑:更大的问题”部分得到解决
在 Maxima 中是否有一个函数可以 return 变量的类型?
我不确定 type
是否是正确的词(我对此很陌生,但感觉它可能具有特定的技术意义),我正在寻找的是一个函数如果变量 x
是数字或数组,则可以 return true
或 false
,例如如果 x : 6;
IsArray(x) = false
IsNumber(x) = true
或者,例如如果 y : [1,2,3]
;
IsArray(y) = true;
IsNumber(y) = false;
我尝试搜索 Maxima 文档,但没有找到任何内容。任何帮助将不胜感激。
编辑:更大的问题。
我编写了一个函数,它将 return 一个范围内的随机值 y
,同时确保 y
不同于另一个值 b
:
DistinctValue(x,y,LowerLim,UpperLim):= block(
[newY:y],
if x = newY
then newY:DistinctValue(x,rand_range(LowerLim,UpperLim),LowerLim,UpperLim)
else newY:y, return(newY));
其中 rand_range(LowerLim,UpperLim)
是另一个选择随机整数的自定义函数 LowerLim
≤ x ≤ UpperLim
.
我很快就意识到有时我会需要几个这样的不同值,所以我调整了上面的代码,以便它可以将数组作为参数:
DistinctValue(x,y,LowerLim,UpperLim):= block([newY:y],
for i:1 thru length(x)
do if x[i] = newY
then newY:DistinctValue(x,rand_range(LowerLim,UpperLim),LowerLim,UpperLim),
return(newY));
虽然我知道后者可用于从范围中排除单个数字的情况,只需将其放在方括号中即可,但我希望学会编写一个可以采用 x
作为一个数字或一个数组。我认为最简单的方法是使用 if / else 语句来评估变量 x
的类型,例如
DistinctValue(x,y,LowerLim,UpperLim):= block([newY:y],
/* if it's a list, run the list version of the function */
if IsList(x)
then
for i:1 thru length(x)
do if x[i] = newY
then newY : DistinctValue(x, rand_range(LowerLim,UpperLim), LowerLim, UpperLim)
/* otherwise run the number version of the function */
else
if x = newY
then newY : DistinctValue(x, rand_range(LowerLim,UpperLim), LowerLim,UpperLim)
else newY:y,,
return(newY));
虽然这看起来是多余的,但我们正在另一个相当复杂的环境中实现 Maxima,它会被比我经验更少的人使用。此外,我希望遇到在不久的将来,它更有必要而不是一种选择的其他情况。
关于 DistinctValue 函数,以下是我将如何实现一个函数,该函数 returns 一个范围内的随机值,该范围不同于单个值或所有值列表。
DistinctValue(x, LowerLim, UpperLim) :=
if listp(x)
then block([y: rand_range(LowerLim, UpperLim)],
if member(y, x) /* need to try again */
then DistinctValue(x, LowerLim, UpperLim)
else y)
else DistinctValue([x], LowerLim, UpperLim);
这与上面显示的有些不同;这可能意味着我误解了要求。我会让你来判断。
rand_range
可以表示为
rand_range(LowerLim, UpperLim) := LowerLim + random(UpperLim - LowerLim + 1);
UpperLim - LowerLim + 1
确保可以返回UpperLim
,否则rand_range
的最大随机值是UpperLim
减1,假设LowerLim
和UpperLim
是整数。
编辑:似乎有效——在这里我已经 load(descriptive);
获得 discrete_freq
.
(%i32) makelist (DistinctValue ([13, 15, 17], 12, 18), 100);
(%o32) [18, 18, 14, 16, 18, 16, 12, 12, 18, 18, 12, 14, 12, 12,
18, 18, 14, 12, 12, 14, 16, 18, 12, 16, 12, 16, 14, 18, 16, 12,
14, 16, 14, 16, 16, 12, 14, 18, 14, 14, 14, 12, 16, 18, 14, 18,
18, 14, 14, 18, 12, 16, 18, 12, 16, 16, 12, 14, 16, 18, 16, 14,
16, 12, 16, 12, 14, 18, 16, 14, 12, 18, 14, 12, 16, 18, 12, 12,
14, 14, 18, 16, 18, 14, 14, 18, 16, 14, 12, 12, 14, 12, 18, 18,
12, 18, 12, 18, 18, 18]
(%i33) discrete_freq (%);
(%o33) [[12, 14, 16, 18], [26, 25, 21, 28]]
N.B. 标题中的问题在下面的“编辑:更大的问题”部分得到解决
在 Maxima 中是否有一个函数可以 return 变量的类型?
我不确定 type
是否是正确的词(我对此很陌生,但感觉它可能具有特定的技术意义),我正在寻找的是一个函数如果变量 x
是数字或数组,则可以 return true
或 false
,例如如果 x : 6;
IsArray(x) = false
IsNumber(x) = true
或者,例如如果 y : [1,2,3]
;
IsArray(y) = true;
IsNumber(y) = false;
我尝试搜索 Maxima 文档,但没有找到任何内容。任何帮助将不胜感激。
编辑:更大的问题。
我编写了一个函数,它将 return 一个范围内的随机值 y
,同时确保 y
不同于另一个值 b
:
DistinctValue(x,y,LowerLim,UpperLim):= block(
[newY:y],
if x = newY
then newY:DistinctValue(x,rand_range(LowerLim,UpperLim),LowerLim,UpperLim)
else newY:y, return(newY));
其中 rand_range(LowerLim,UpperLim)
是另一个选择随机整数的自定义函数 LowerLim
≤ x ≤ UpperLim
.
我很快就意识到有时我会需要几个这样的不同值,所以我调整了上面的代码,以便它可以将数组作为参数:
DistinctValue(x,y,LowerLim,UpperLim):= block([newY:y],
for i:1 thru length(x)
do if x[i] = newY
then newY:DistinctValue(x,rand_range(LowerLim,UpperLim),LowerLim,UpperLim),
return(newY));
虽然我知道后者可用于从范围中排除单个数字的情况,只需将其放在方括号中即可,但我希望学会编写一个可以采用 x
作为一个数字或一个数组。我认为最简单的方法是使用 if / else 语句来评估变量 x
的类型,例如
DistinctValue(x,y,LowerLim,UpperLim):= block([newY:y],
/* if it's a list, run the list version of the function */
if IsList(x)
then
for i:1 thru length(x)
do if x[i] = newY
then newY : DistinctValue(x, rand_range(LowerLim,UpperLim), LowerLim, UpperLim)
/* otherwise run the number version of the function */
else
if x = newY
then newY : DistinctValue(x, rand_range(LowerLim,UpperLim), LowerLim,UpperLim)
else newY:y,,
return(newY));
虽然这看起来是多余的,但我们正在另一个相当复杂的环境中实现 Maxima,它会被比我经验更少的人使用。此外,我希望遇到在不久的将来,它更有必要而不是一种选择的其他情况。
关于 DistinctValue 函数,以下是我将如何实现一个函数,该函数 returns 一个范围内的随机值,该范围不同于单个值或所有值列表。
DistinctValue(x, LowerLim, UpperLim) :=
if listp(x)
then block([y: rand_range(LowerLim, UpperLim)],
if member(y, x) /* need to try again */
then DistinctValue(x, LowerLim, UpperLim)
else y)
else DistinctValue([x], LowerLim, UpperLim);
这与上面显示的有些不同;这可能意味着我误解了要求。我会让你来判断。
rand_range
可以表示为
rand_range(LowerLim, UpperLim) := LowerLim + random(UpperLim - LowerLim + 1);
UpperLim - LowerLim + 1
确保可以返回UpperLim
,否则rand_range
的最大随机值是UpperLim
减1,假设LowerLim
和UpperLim
是整数。
编辑:似乎有效——在这里我已经 load(descriptive);
获得 discrete_freq
.
(%i32) makelist (DistinctValue ([13, 15, 17], 12, 18), 100);
(%o32) [18, 18, 14, 16, 18, 16, 12, 12, 18, 18, 12, 14, 12, 12,
18, 18, 14, 12, 12, 14, 16, 18, 12, 16, 12, 16, 14, 18, 16, 12,
14, 16, 14, 16, 16, 12, 14, 18, 14, 14, 14, 12, 16, 18, 14, 18,
18, 14, 14, 18, 12, 16, 18, 12, 16, 16, 12, 14, 16, 18, 16, 14,
16, 12, 16, 12, 14, 18, 16, 14, 12, 18, 14, 12, 16, 18, 12, 12,
14, 14, 18, 16, 18, 14, 14, 18, 16, 14, 12, 12, 14, 12, 18, 18,
12, 18, 12, 18, 18, 18]
(%i33) discrete_freq (%);
(%o33) [[12, 14, 16, 18], [26, 25, 21, 28]]