Matlab | Matrix Function of Several Variables - function

I'm working on Matlab and I need to define a matrix function that depends on several variables.
For example, I have this vectors:
t=[1,2,3,4,5,6,7,8,9,10]
y=[1,2,3,4,5,6,7,8,9,10]
That can contain any real numbers or have any length (same length for t and y, I called it NumData).
I have a function that depends on some parameters P1, P2,...,P5. What I want to do is to form a Matrix (NumData x 5) that depends of p, a vector of parameters:
I don't know how to step further. I thought of define a Matrix:
Matrix = ones(NumData,NumParameters)
But when I try to assign, for example
Matrix(1,3) = p(1)+3*p(2)
I got an error.
I tried to define:
Matrix(1,3)=#(p) p(1)+3*p(2)
But it's useless...
I tried to define the matrix in code, like this:
J=#(p) [1 1 1 exp(-p(5)) -p(4)*exp(-p(5))
1 2 4 exp(-2*p(5)) -p(4)*exp(-2*p(5))
1 3 9 exp(-3*p(5)) -p(4)*exp(-3*p(5))
1 4 16 exp(-4*p(5)) -p(4)*exp(-4*p(5))
1 5 25 exp(-5*p(5)) -p(4)*exp(-5*p(5))]
but it isn't good because this is for a specific case...
My main goal is to form J from t vector, and that J depends on the vector parameter p so I can evaluate later
A= J(1,2,1,2,2)
for example, and then factorize A as QR.
Do you have any suggestions? Or I am asking too much for Matlab?

I'm not 100% sure of what you are trying to do, but let me give you some examples of things that will work, in the hopes that it can help you a bit.
p=[1 2 3 4 5];
M=zeros(3,2);
M=[p(1) p(2) p(5); p(3)/p(2) p(5)^p(2) exp(p(3))]

Related

Pytorch parallel functional calls for multiple locations in a tensor

Does anyone know if there is a function in PyTorch that allows you to call a particular function for all the locations in a tensor where a condition is satisfied?
For example, for all the locations in a tensor where the value is equal to 100, a function has to be called without using any for loops. I want to modify other tensors for these locations. I know I can just get the list of locations and then call the function for each location but I want to avoid that. Thank you for your help.
Something like torch.where(a==100,function1())
Adding more details after the request in the comments:
function1(x,y): #(x,y) are co-ordinates
... some code based on (x,y)...
a[x,y] = 20
b[x,y] = 10
Let's assume we have 2 2D(single row) tensors a = [1 2 100 100 5 6 200 8 2] and b=[3 4 5 5 6 10 3 8 9].
Now I want to pass the coordinates of where a == 100 in our case (0,2) and (0,3) to function1 and modify the values of a and b at those locations. I hope this helps.

How to plot a 2d Function in MATLAB

I am trying to plot a simple equation in MATLAB.
The equation is
z = x^2 - y^2, for -3 <= x <= 3, -3 <= y <= 3.
The current code that I have is
x = -3:3;
y = -3:3;
z = (x.^2) - (y.^2);
plot(z)
The result is
Please help me in this case because I am not sure if the code and graph is correct. Thank you very much.
This is not a piecewise function. A Piecewise Function is a function defined by multiple sub-functions, where each sub-function applies to a different interval in the domain. There is only one function here that takes two arrays of the same length. The calculations yield a vector of zeros, due to the input arrays. If you change either one of the vectors, that is "x" or "y", you will see a nonzero plot. Your code works as expected.
There is a lot going wrong here: Let's start at the beginning:
x = -3:3;
y = -3:3;
If we evaluate these they both will return an vector of integers:
x =
-3 -2 -1 0 1 2 3
This means that the grid on which the function is evaluated is going to be very coarse. To alleviate this you can define a step size, e.g. x = 3:0.1:3 or use linspace, in which case you set the number of samples, so e.g. x = linspace(-3, 3, 500). Now consider the next line:
z = (x.^2) - (y.^2);
If we evaluate this we get
z =
0 0 0 0 0 0 0
and you plot this vector with the 2d-plotting function
plot(z)
which perfectly explains why you get a straight line. This is because the automatic broadcasting of the arithmetic operators like minuse (-) just subtracts values entry-wise. You however want to evaluate z for each possible pair of values of x and y. To do this and to get a nice plot later you should use meshgrid, and use a plotting function like mesh to plot it. So I'd recommend using
[X,Y] = meshgrid(x,y);
to create the grid and then evaluate the function on the grid as follows
Z = X.^2 - Y.^2;
and finally plot your function with
mesh(X,Y,Z);

Applying a function to multiple rows of a data frame where the row is an argument in the function in R

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!

Trying to find a way to construct Julia `generator`

I'm new to Julia.
I mainly program in python.
In python,
if you want to iterate over a large set of values,
it is typical to construct a so-called generator to save memory usage.
Here is one example code:
def generator(N):
for i in range(N):
yield i
I wonder if there is anything alike in Julia.
After reading julia manual,
#task macro seems to have the same (or similar) functionality as generator in python.
However,
after some experiments,
the memory usage seems to be larger than usual array in julia.
I use #time in IJulia to see the memory usage.
Here is my sample code:
[Update]: Add the code for generator method
(The generator method)
function generator(N::Int)
for i in 1:N
produce(i)
end
end
(generator version)
function fun_gener()
sum = 0
g = #task generator(100000)
for i in g
sum += i
end
sum
end
#time fun_gener()
elapsed time: 0.420731828 seconds (6507600 bytes allocated)
(array version)
function fun_arry()
sum = 0
c = [1:100000]
for i in c
sum += i
end
sum
end
#time fun_arry()
elapsed time: 0.000629629 seconds (800144 bytes allocated)
Could anyone tell me why #task will require more space in this case?
And if I want to save memory usage as dealing with a large set of values,
what can I do?
I recommend the "tricked out iterators" blogpost by Carl Vogel, which discusses julia's iterator protocol, tasks and co-routines in some detail.
See also task-aka-coroutines in the julia docs.
In this case you should use the Range type (which defines an iterator protocol):
julia> function fun_arry()
sum = 0
c = 1:100000 # remove the brackets, makes this a Range
for i in c
sum += i
end
sum
end
fun_arry (generic function with 1 method)
julia> fun_arry() # warm up
5000050000
julia> #time fun_arry()
elapsed time: 8.965e-6 seconds (192 bytes allocated)
5000050000
Faster and less memory allocated (just like xrange in python 2).
A snippet from the blogpost:
From https://github.com/JuliaLang/julia/blob/master/base/range.jl, here’s how a Range’s iterator protocol is defined:
start(r::Ranges) = 0
next{T}(r::Range{T}, i) = (oftype(T, r.start + i*step(r)), i+1)
next{T}(r::Range1{T}, i) = (oftype(T, r.start + i), i+1)
done(r::Ranges, i) = (length(r) <= i)
Notice that the next method calculates the value of the iterator in state i. This is different from an Array iterator, which just reads the element a[i] from memory.
Iterators that exploit delayed evaluation like this can have important performance benefits. If we want to iterate over the integers 1 to 10,000, iterating over an Array means we have to allocate about 80MB to hold it. A Range only requires 16 bytes; the same size as the range 1 to 100,000 or 1 to 100,000,000.
You can write a generator method (using Tasks):
julia> function generator(n)
for i in 1:n # Note: we're using a Range here!
produce(i)
end
end
generator (generic function with 2 methods)
julia> for x in Task(() -> generator(3))
println(x)
end
1
2
3
Note: if you replace the Range with this, the performance is much poorer (and allocates way more memory):
julia> #time fun_arry()
elapsed time: 0.699122659 seconds (9 MB allocated)
5000050000
This question was asked (and answered) quite a while ago. Since this question is ranked high on google searches, I'd like to mention that both the question and answer are outdated.
Nowadays, I'd suggest checking out https://github.com/BenLauwens/ResumableFunctions.jl for a Julia library with a macro that implements Python-like yield generators.
using ResumableFunctions
#resumable function fibonnaci(n::Int) :: Int
a = 0
b = 1
for i in 1:n-1
#yield a
a, b = b, a+b
end
a
end
for fib in fibonnaci(10)
println(fib)
end
Since its scope is much more limited than full coroutines, it is also an order of magnitude more efficient than pushing values into a channel since it can compile the generator into a FSM. (Channels have replaced the old produce() function mentioned in the question and previous answers).
With that said, I'd still suggest pushing into a channel as your first approach if performance isn't an issue, because resumablefunctions can sometimes be finicky when compiling your function and can occasionally hit some worst-case behaviour. In particular, because it is a macro that compiles to an FSM rather than a function, you currently need to annotate the types of all variables in the Resumablefunction to get good performance, unlike vanilla Julia functions where this is handled by JIT when the function is first called.
I think that Task has been superseded by Channel(). The usage in terms of Ben Lauwens's Fibonacci generator is:
fibonacci(n) = Channel(ctype=Int) do c
a = 1
b = 1
for i in 1:n
push!(c, a)
a, b = b, a + b
end
end
it can be used using
for a in fibonacci(10)
println(a)
end
1
1
2
3
5
8
13
21
34
55

MatLab - Applying a function to each row in a matrix

I have a matrix with rows of 4 integers, with an unspecified number of columns (depends on the text file).
I'm wanting to apply a function to each row of the matrix, independently. The function has 4 inputs, and 2 outputs.
I'm trying to use the arrayfun function to do this, but whenever I call the function, I get an error saying: "Not enough input arguments."
Here is the function call:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1:4)), 1:size(B));
where b is an n by 4 matrix.
Here is the function:
function [gain,phase] = GainPhaseComp(InAmp,InPhase,OutAmp,OutPhase)
gain = 20*log10(OutAmp\InAmp);
phase = (OutPhase - InPhase);
end
Any help would be greatly appreciated!
Your function GainPhaseComp has 4 input arguments, but you pass only 1 row vector. Vector with 4 elements is still one variable, not 4. You need either to change the function definition or split the vector elements.
1st option:
function [gain,phase] = GainPhaseComp(inputvector)
% function body
2nd option:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1),B(x,2),B(x,3),B(x,4)), 1:size(B,1));