Sorry for the noob question, but I am a beginner in MATLAB. I need to do the following task, but am stuck. "Write a function that takes three arguments x, a, b, where x is a matrix, and a and b are scalars. The function returns the number of elements in x that lie in the interval [a, b]." Here is what I have so far.
function y = count(x,a,b);
for value=a:b
length(value)
end
I need to call the function in the command prompt with the following line:
count(randn(20, 20), 0, 5)
However, I'm not getting anything close to the correct answer. Can anyone point me in the right direction? Thank you.
As Jonas suggested nnz and sum are faster options than numel(find(...)), with sum being the fastest, therefore:
function y = count(x,a,b);
y = sum(x(:)>a & x(:)<b);
Related
I want to define a function that takes an input n and gives back the function f defined by f(x) = x^n.
So I wrote the following piece of code on Scilab:
function [f]=monomial(n)
function [z] = g(x)
z = x^n
endfunction
f = g
endfunction
Unfortunately when I evaluate monomial(3)(2) I get 32. whereas it should be 8.
I hope someone could point out where I have gone wrong when writing this function.
Could somebody help me please?
I cleared all variables and reran the code and it told me that n is not defined within g, therefore is there a way to overcome this problem?
the more secure way to do this is by using deff :
function [f]=monomial(n)
f = deff('z=g(x)','z=x^'+string(n));
endfunction
otherwise n could be polluted by current scope
--> monomial(2)(8)
ans =
64.
I want to plot a function using surface in Julia. I manage to plot te desired function:
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)
However, I would f(*) to be a proper function over which I could also optimize (e.g. utility maximisation in economics). This is my attempt:
function Utility(x1, x2)
u= x.^0.2 .* y.^0.8
return u
end
But it unfortunately does not work. Can anybody help me?
Best
Daniel
I think Benoit's comment really should be the answer, but let me expand a little bit.
First of all, an inline function definition is not any different from a multi-line function definiton (see the first two examples in the docs here). Therefore, doing
utility(x, y) = x^0.2 * y^0.8
will give you a function that works exactly like
function utility(x, y)
x^0.2 * y^0.8
end
However, your Utility function is actually different from your f function - you are defining it with the arguments x1 and x2, but in the function body you are using y rather than x2.
This would ordinarily raise an undefined variable error, except that in the code snippet you posted, y is already defined in global scope as the range 0:0.1:4, so the function will use this:
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
...
this is also where your introduction of broadcasting in the Utility function (the second difference between your two examples as Benoit pointed out) comes back to haunt you: calling the function while relying on it to use the global variable y would error immediately without broadcasting (as you can't exponentiate a range):
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)
with broadcasting, however, this exponentiation works and returns the full range, with every element of the range exponentiated. Thus, your function returns an array rather than a single number (as you can see above from my call to u(2.0, 0.0). This is what Plots complains about - it doesn't know how to plot an array, when it expects to just be plotting a single data point.
Apologies for the rather long name, but I wanted to be specific. I am rather new to R and coding so please go easy on me.
I have a function as follows:
myfun = function(x, y, g) {return(1 / (1 + exp(y*g%*%x)))}
where x is any data frame with n rows and d columns, y is a scalar and integer, and g is a vector of length d (i.e. same as x). I want to run this function for each row of x without using loops.
I have tried various function in the apply family similar to the code below:
apply(x = a, 1, myfun(y = 1, g = b)
where a is a 3x3 data frame and b is a vector 3 elements long. The above code gives an error that I am missing an argument from myfun, but I am obviously clueless on what to try.
Thanks for any help in advance!
Edit: My actual data frame is huge, sparse, and not very straight forward (I think), so I will include an example data frame and other variables:
a = data.frame(c1 = seq(1,3,1), c2 = seq(4,6,1), c3 = seq(7,9,1))
b = c(1,2,3)
c = 1
Also, I think I may have not clearly stated an important piece of information. I want to actually do a summation of myfun over all the rows and values of b, so I actually want the following:
answer = myfun(a[1,], c, b[1]) + myfun(a[2,], c, b[2]) + myfun(a[3,], c, b[3])
In other words, a[1,] should be applied to myfun with b[1] as they are grouped together. I also made an edit to the function above because I forgot to include return(). Hopefully, this makes things more clear. Apologies for the confusion!
I am studying for a final, and I have a practice problem here.
The question asks for the result of
val y = ref 1;
fun f x = (!y) + (x + x);
(f (y := (!y)+1; !y)) + (!y);
under the following parameter passing techniques:
Call by value
Call by name
Call by need.
It seems to me that for call by value, the answer is 8.
However, I believe the answer for call by name is also 8, but I would expect it to be different. The reason I think it is 8:
y := (!y)+1 derefs y as 1, adds 1, and then sets y to 2
!y in line 3 serves as the argument to f, and since it is being dereferenced it is
passed as a value rather than as a reference (this may be where I am
going wrong?)
The function call returns 6, but does not set y as y was passed in as a value from the previous step
6 is added to the dereferenced value of y, which is 2.
This returns 8
Is this the correct answer, and if not, can someone please point out where I have gone wrong? Also, can someone explain to me how call by need would work in this situation also?
Many thanks.
I found out how it works:
(y := (!y)+1; !y) is the parameter passed to f.
f then looks like:
fun f x = (!y) + ((y:= (!y)+1; !y) + (y:= (!y)+1; !y));
so this ends up being 1+2+3, and the final step + (!y) adds 3 as this is the current value of y, giving 9.
Thanks for pointing out that I was still doing call-by-value.
I am trying to plot the function
f(x, y) = (x – 3).^2 – (y – 2).^2.
x is a vector from 2 to 4, and y is a vector from 1 to 3, both with increments of 0.2. However, I am getting the error:
"Subscript indices must either be real positive integers or logicals".
What do I do to fix this error?
I (think) I see what you are trying to achieve. You are writing your syntax like a mathematical function definition. Matlab is interpreting f as a 2-dimensional data type and trying to assign the value of the expression to data indexed at x,y. The values of x and y are not integers, so Matlab complains.
If you want to plot the output of the function (we'll call it z) as a function of x and y, you need to define the function quite differently . . .
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
z = f( repmat(x(:)',numel(y),1) , repmat(y(:),1,numel(x) ) );
surf(x,y,z);
xlabel('X'); ylabel('Y'); zlabel('Z');
This will give you an output like this . . .
The f = #(x,y) part of the first line states you want to define a function called f taking variables x and y. The rest of the line is the definition of that function.
If you want to plot z as a function of both x and y, then you need to supply all possible combinations in your range. This is what the line containing the repmat commands is for.
EDIT
There is a neat Matlab function meshgrid that can replace the repmat version of the script as suggested by #bas (welcome bas, please scroll to bas' answer and +1 it!) ...
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
[X,Y] = meshgrid(x,y);
surf(x,y,f(X,Y));
xlabel('x'); ylabel('y'); zlabel('z');
I typically use the MESHGRID function. Like so:
x = 2:0.2:4;
y = 1:0.2:3;
[X,Y] = meshgrid(x,y);
F = (X-3).^2-(Y-2).^2;
surf(x,y,F);
xlabel('x');ylabel('y');zlabel('f')
This is identical to the answer by #learnvst. it just does the repmat-ing for you.
Your problem is that the function you are using uses integers, and you are trying to assign a double to it. Integers cannot have decimal places. To fix this, you can make it to where it increases in increments of 1, instead of 0.2