矢量函数始终是常量

时间:2016-09-11 22:31:57

标签: matlab vector octave

MATLAB的新手,我需要以下问题的帮助。

我想创建一个函数 val = F(v,e),它接收两个输入 v ,一个 1xn 向量,以及标量 e ,并输出一个标量 val ,用于计算向量 ve 的非零项,即向量 v 从所有每个条目中减去 e 。我的功能代码如下:

function val = eff(vec, e)
val = sum( (vec - e > 0) );
end

当我在单点评估函数时,它可以正常工作。但我想在(0,1)上绘制这个函数的图。绘制它在e的整个范围内给出恒定值。我在主

上使用以下代码
figure
e = linspace(0,1);
plot(e, eff(rand(1,100),e),'o',e, e)

另外,当我使用一个小向量,比如rand(1,10)时,我收到以下错误信息:

>Error using  -
> 
>Matrix dimensions must agree.
>
>Error in eff (line 3)
>
>val = sum( (vec - e > 0 ));

我的功能是否因矩阵尺寸过于粗心?或者是否有更简单的方法来评估矢量范围内的 eff

提前致谢。

3 个答案:

答案 0 :(得分:1)

您创建了一个 Designed 的函数,仅应用于标量e参数,并将e作为数组传递可能会导致错误......但是你用e = linspace(0,1)来调用它,其中一个数组。

e大小为10时的特定错误告诉您不能从大小为100的矩阵中减去它。

e 发生vec具有相同的大小时,您的函数会减去两个大小相等的数组,并返回它们的和,即标量。因此,你的情节基本上是做plot(a_range, a_scalar)之类的事情,这就是它看起来不变的原因。

相反,您应该为for循环中的V的每个值收集一个数组e,或者使用arrayfun,例如。

e = linspace(0,1);
V = arrayfun(@eff, e);

然后针对e

绘制V

或者,您可以重写您的函数,使其期望e为数组,并且您的返回值是与e大小相同的数组,并填充相应的值。

答案 1 :(得分:1)

不使用arrayfun,您的任务也可以使用广播完成。我注意到你有这个问题标记为Octave以及Matlab。当您尝试使用不同维度的向量进行元素运算时,Octave会使用自动广播。 Matlab可以使用bsxfun函数进行广播。 (如果你想要在任一程序中运行的代码,Octave也可以使用bsxfun。)另外,根据发行说明,我相信Matlab 2016b现在将包括自动广播,虽然我还不能确认它的行为与Octave相同

因为您的向量vece都是行向量,当您尝试减去它们时,Matlab / Octave将减去每个元素(如果它们具有相同的大小),或者如果它们给出大小不匹配错误不要。

如果您将其中一个向量创建为列向量,则广播可以接管。一个简单的例子:

>> a = [1:4]
a =

   1   2   3   4

>> b = [1:4]'
b =

   1
   2
   3
   4

>> a-b  //Error in Matlab versions before 2016b
ans =

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

>> bsxfun(@minus,a,b)   //works under Octave or Matlab
ans =

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

因此,如果您正在运行Octave,如果您只是重写函数,则代码将正确运行,因此向量使用不同的维度。有很多方法可以做到这一点,但由于Matlab和Octave都默认为列排序,您可以使用:运算符强制它们以您想要的方式工作。 E.g:

>> a = [1:4]
a =

   1   2   3   4

>> a(:)
ans =

   1
   2
   3
   4

>> a(:)'
ans =

   1   2   3   4    

>> b = [1:4]'
b =

   1
   2
   3
   4

>> b(:)
ans =

   1
   2
   3
   4

>> b(:)'
ans =

   1   2   3   4

所以,毕竟,你可以重写你的功能:

function val = eff(vec, e)
  vec = vec(:);
  e = e(:)';
  val = sum ( (vec-e ) > 0 );
end

如果你正在运行matlab,或者你想要可以在Octave和Matlab中运行的代码,你可以用以下代码替换函数的最后一行:

sum ( bsxfun(@minus,vec,e) > 0 )

最后,如果你愿意,你可以添加一些' isvector'在函数开头的错误检查,以防您不小心将数组传递给它。请注意,如果我选择制作' vec'行向量和' e'列向量我将不得不告诉sum函数总和的哪个维度。 (它默认为对每一列求和并返回一个行向量,它与我上面的选择相匹配。)

答案 2 :(得分:0)

只要e是缩放器而不是数组或矩阵,您的功能就可以正常工作。然后,您可以循环或使用arrayfun(已经回答)以获得最终答案

ActiveRecord::Schema.define(version: 20160911213902) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "roles", force: :cascade do |t|
    t.string   "name"
    t.integer  "resource_id"
    t.string   "resource_type"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

add_index "roles", ["name", "resource_type", "resource_id"], name:  "index_roles_on_name_and_resource_type_and_resource_id", using: :btree

add_index "roles", ["name"], name: "index_roles_on_name", using: :btree

  create_table "royce_connector", force: :cascade do |t|
    t.integer  "roleable_id",   null: false
    t.string   "roleable_type", null: false
    t.integer  "role_id",       null: false
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "royce_connector", ["role_id"], name: "index_royce_connector_on_role_id", using: :btree
  add_index "royce_connector", ["roleable_id", "roleable_type"], name: "index_royce_connector_on_roleable_id_and_roleable_type", using: :btree

  create_table "royce_role", force: :cascade do |t|
    t.string   "name",       null: false
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "royce_role", ["name"], name: "index_royce_role_on_name", using: :btree

  create_table "sessions", force: :cascade do |t|
    t.string   "session_id", null: false
    t.text     "data"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", unique: true, using: :btree
  add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree

  create_table "users", force: :cascade do |t|
    t.string   "email"
    t.string   "name"
    t.string   "login_token"
    t.datetime "login_token_valid_until"
    t.datetime "created_at",              null: false
    t.datetime "updated_at",              null: false
  end

  create_table "users_roles", id: false, force: :cascade do |t|
    t.integer "user_id"
    t.integer "role_id"
  end

 add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree

 create_table "vendors", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
 end

  create_table "visits", force: :cascade do |t|
    t.string   "country"
    t.datetime "visited_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end