Функция и построение поверхности Джулия

#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 and x2 вместо x and y , и вы не должны передавать умножение (использовать * вместо .* ), чтобы ваш график работал.

Ответ №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 примере выше — if a — это диапазон (т. Е. Объект типа StepRangeLen ), и Вы пытаетесь это сделать a^0.2 , это не сработает, поскольку возведение в степень не определено для диапазона. Если вы хотите возведение в степень каждого элемента в диапазоне, вам необходимо передать ^ оператор: a .^ 0.2