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 ?
提前致谢。
答案 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相同
因为您的向量vec
和e
都是行向量,当您尝试减去它们时,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