【问题标题】:First N values of a function with two inputs具有两个输入的函数的前 N ​​个值
【发布时间】:2014-05-27 13:45:13
【问题描述】:

我有一个带有两个整数输入的函数,如下所示:

function f = func(n, m)
    a = 2;
    b = 1;
    f = sqrt((n/a)^2 + (m/b)^2);
end

m 和 n 是整数并且大于或等于零。 f 的前几个值和它们出现的输入如下:

n ----- m ----- f

0 ----- 0 ----- 0

1 ----- 0 ----- 0.5

2 ----- 0 ----- 1

0 ----- 1 ----- 1

1 ----- 1 ----- 1.118

等等。我想获得 f 的前 N ​​个值及其各自的 n 和 m。在matlab中有没有简单的方法来做到这一点?

【问题讨论】:

  • 使用0, 1 and 2,您似乎可以在f 中获得9 值,那么如果您的N 大于9 怎么办?还是你的意思是0, 1, 2, 3 and so on till N
  • 在这个例子中,N 是 5,所以我得到了 f 的前 5 个值。正如您所见,在 (2,0) 输入为 (0,1) 后,以获得与前一个最接近的 f 值。所以他们没有任何普遍的秩序。我需要找到 n 和 m 的正确顺序来计算 f 的升序。
  • 您可以使用任何答案,然后对结果值f 进行排序并取前 N 个元素。不明显的一点是要计算的网格的大小 n*m 不会丢失任何值,因为它很大程度上取决于函数func

标签: arrays matlab combinations


【解决方案1】:

代码

%// Parameters
N = 5
a = 2;
b = 1;

%// Extents of n and m would be from 0 to N-1 to account for all possible
%// minimum values of f results resulting from their use 
len1 = N-1

%// Create n and m for maximum possible combinations scenario, but save
%// them as n1 and m1 for now, as the final ones would be chopped versions
%// of them.
[n1,m1] = ndgrid(0:len1,0:len1)

%// Get corresponding f values, but store as f1, for the same chopping reason
f1 = sqrt((n1(:)./a).^2 + (m1(:)./b).^2);

%// Sort f1 so that the smallest N values from it could be choosen and also
%// get the selected row indices based on the sorting as row1
[f1,row1] = sort(f1)

%// Choose n and m based on the sorted indices and also chop off at N.
%// Use these n and m values to finally get f
n = n1(row1(1:N))
m = m1(row1(1:N))
f = f1(1:N)

输出

如果 N = 5,你会得到 -

n =
     0
     1
     2
     0
     1

m =
     0
     0
     0
     1
     1

f =
         0
    0.5000
    1.0000
    1.0000
    1.1180

如果 N = 9,你会得到 -

n =
     0
     1
     2
     0
     1
     2
     3
     3
     4
m =
     0
     0
     0
     1
     1
     1
     0
     1
     0
f =
         0
    0.5000
    1.0000
    1.0000
    1.1180
    1.4142
    1.5000
    1.8028
    2.0000

【讨论】:

  • +1 和我的做法差不多。也许多解释一点会更好。
  • @DennisJaheruddin 谢谢哥们!并且肯定会出现!
  • 谢谢 这真的很好。我也非常感谢您的解释。
  • @soroosh.strife 用一些 cmets 编辑。看看它们是否有意义!
  • 我认为你应该从 len1 中省略 sqrt。这样会丢失一些有效结果。
【解决方案2】:

meshgridarrayfun 可用于为输入范围生成输出数组

代码

nValues = 0:2 
mValues = 0:3

[ii,jj] = meshgrid(mValues,nValues)
output = arrayfun(@func,ii,jj)

可以修改两个值向量以获取所需值的范围

输出

output =

         0    0.5000    1.0000    1.5000
    1.0000    1.1180    1.4142    1.8028
    2.0000    2.0616    2.2361    2.5000

要给出类似于问题中的矩阵的结果,可以使用以下方法(感谢@Divakar)

[jj(:),ii(:),arrayfun(@func,jj(:),ii(:))]

ans =

         0         0         0
    1.0000         0    0.5000
    2.0000         0    1.0000
         0    1.0000    1.0000
    1.0000    1.0000    1.1180
    2.0000    1.0000    1.4142
         0    2.0000    2.0000
    1.0000    2.0000    2.0616
    2.0000    2.0000    2.2361
         0    3.0000    3.0000
    1.0000    3.0000    3.0414
    2.0000    3.0000    3.1623

【讨论】:

  • 不应该是ii(:)jj(:)arrayfun 吗? meshgrid btw 的好主意! +1
  • 好主意,我要添加它以匹配使用 ii(:) 和 jj(:) 给出的格式
  • 它实际上接近我正在寻找的东西。我应该对这些结果进行排序并选择其中的前 N ​​个。难道没有不需要计算额外结果的方法吗?
  • 对于给出的函数,它可能通过计算 m 和 n 值之间的关系得到相同的结果(例如 [2x,0] 和 [0,x]),尽管假设这只是一个示例函数。在考虑将它用于许多不同的功能时,我无法想象它比蛮力更有效
【解决方案3】:

这样的事情(可能相当低效)?

N = 100 % stop 
i = 0
n = 0
m = 0
nout = [n]
mout = [m]
fout = [f(n,m)]
while i ~= N
    a = f(n+1,m)
    b = f(n,m+1)
    if (a > b)
        m = m + 1
        nout = [nout n]
        mout = [mout m]
        fout = [fout b]
    else 
        n = n + 1
        nout = [nout n]
        mout = [mout m]
        fout = [fout a]
    end if
    i = i + 1
end while

【讨论】:

  • 我在这里要做的是计算函数的正确输入值,以免错过中间的任何内容并获得连续的输出。我不能用手来做,因为 N 可能有点大。
  • 我想我误解了这个问题。您想为 [0..N] 中的所有 PAIRS 值计算 f 对吗?
  • 没有。在上面给出的示例中,我计算了 f 的前 5 个值。但为了做到这一点,我尝试了 m 和 n 值的不同组合,以确保这些 f 不能有 0 到 1.118 范围内的任何其他值。问题是我需要例如 f 的前 100 个值而不是 5,但我不知道要使用哪些输入组合。
  • 我现在明白了。您实际上是在对抛物面上的数字进行排序:wolframalpha.com/input/?i=%28x%2F2%29^2+%2B+y^2 效率不高,但您可以简单地遍历 n 和 m 的值,对一个数字加 1,计算 func 的值对于那个特定的 (n,m) 对,并在 f 的较小值上增长向量。我会编辑我的帖子
  • 实际上,有时当我将一个输入增加一个时,如果我减少另一个输入,我会得到更接近前一个输入的 f 值。就像我的示例中的 (2,0) 和 (0,1) 一样。
猜你喜欢
  • 2020-08-25
  • 2022-01-13
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多