#function #plot #julia #surface
#функция #график #Джулия #Поверхность
Вопрос:
Я хочу построить функцию, используя поверхность в Julia. Мне удается построить желаемую функцию:
x = 0:0.1:4
y = 0:0.1:4
f(x,y) = x^0.2 * y^0.8
surface(x, y, f, camera=(10,30),linealpha=0.3, fc=:heat)
Тем не менее, я бы хотел, чтобы f (*) была правильной функцией, которую я мог бы также оптимизировать (например, максимизация полезности в экономике). Это моя попытка:
function Utility(x1, x2)
u= x.^0.2 .* y.^0.8
return u
end
Но, к сожалению, это не работает. Кто-нибудь может мне помочь?
Лучшие
Дэниел
Комментарии:
1. Ваша
f(x,y)
функция правильная, просто она умещается в одной строке. В вашейUtility
функции (и, кстати, рекомендуется использовать нижний регистр для функций) вашими аргументами являютсяx1
andx2
вместоx
andy
, и вы не должны передавать умножение (использовать*
вместо.*
), чтобы ваш график работал.
Ответ №1:
Я думаю, что комментарий Бенуа действительно должен быть ответом, но позвольте мне немного расширить.
Прежде всего, определение встроенной функции ничем не отличается от определения многострочной функции (см. Первые два примера в документации здесь). Поэтому, выполняя
utility(x, y) = x^0.2 * y^0.8
даст вам функцию, которая работает точно так же, как
function utility(x, y)
x^0.2 * y^0.8
end
Однако ваша Utility
функция на самом деле отличается от вашей f
функции — вы определяете ее с помощью аргументов x1
и x2
, но в теле функции вы используете y
вместо x2
.
Обычно это приводит к ошибке неопределенной переменной, за исключением того, что в опубликованном вами фрагменте кода y
она уже определена в глобальной области как диапазон 0:0.1:4
, поэтому функция будет использовать это:
julia> y = 0:0.1:4
0.0:0.1:4.0
julia> u(x1, x2) = x1 .^ 0.2 * y .^ 0.8
u (generic function with 1 method)
julia> u(2.0, 0.0)
41-element Array{Float64,1}:
0.0
0.18205642030260805
0.3169786384922227
...
именно здесь ваше введение широковещательной передачи в Utility
функцию (второе различие между вашими двумя примерами, как указал Бенуа) возвращается, чтобы преследовать вас: вызов функции, полагаясь на нее для использования глобальной переменной y
, немедленно приведет к ошибке без широковещательной передачи (поскольку вы не можете возвести диапазон в степень):
julia> u2(x1, x2) = x1^0.2 * y^0.8
u2 (generic function with 1 method)
julia> u2(2.0, 0.0)
ERROR: MethodError: no method matching ^(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Float64)
однако при широковещательной передаче это возведение в степень работает и возвращает полный диапазон, при этом каждый элемент диапазона возведен в степень. Таким образом, ваша функция возвращает массив, а не одно число (как вы можете видеть выше из моего вызова u(2.0, 0.0)
. Это то, на что жалуется Plots — он не знает, как построить массив, когда он ожидает, что он будет отображать только одну точку данных.
Комментарии:
1. Спасибо, я запустил код. Однако, просто для полноты картины: почему эта функция не возвращает никаких выходных данных?
a = 0:0.1:4; b = 0:0.1:4; f(x,y) = x^0.2 * y^0.8; f(a,b)
?2. Запуск этого фрагмента приводит к ошибкам для меня, и по той же причине, что показана в моем
u2
примере выше — ifa
— это диапазон (т. Е. Объект типаStepRangeLen
), и Вы пытаетесь это сделатьa^0.2
, это не сработает, поскольку возведение в степень не определено для диапазона. Если вы хотите возведение в степень каждого элемента в диапазоне, вам необходимо передать^
оператор:a .^ 0.2