Large matrix for surface plot? - matlab

I'm somewhat new to MATLAB and I'm trying to make a large matrix structured very much like the following example:
C=[1,2,3]
n=[-3,0,3]
X=[f(1,-3),f(1,0),f(1,3);f(2,-3),f(2,0),f(2,3);f(3,-3),f(3,0),f(3,3)]
where f is some function of the values in C and n. I need this sort of matrix, X, so that I can make a surface graph of surf(C,n,X). The issue is that, in my real problem, I need a 51x51 matrix, and I don't know how to make such a matrix without typing out everything (which would be a horrific task).
Could someone please help me understand how to make such a plot? Thank you so much!

Have a look at ndgrid:
>> [ii,jj] = ndgrid(C,n)
ii =
1 1 1
2 2 2
3 3 3
jj =
-3 0 3
-3 0 3
-3 0 3
Then you can get X very easily if f operates element-wise on non-scalar inputs:
X = f(ii,jj);
If f can only take a pair of scalars, try arrayfun:
X = arrayfun(#(x,y)f(x,y),ii,jj);
(Or modify f!)

X = f(C'*ones(1, 51), ones(51, 1)*n))

Related

How to create an Octave function that evaluate the sum of pairs of numbers in the vector?

It's like a reverse version of Pascal's triangle.
I want to create a vector-input function named
y = lastnum(vect) on Octave, that evaluate the sum of each pair of numbers in any vectors to output the single number from the evaluation loops like this
0 1 2 3 4
1 3 5 7
4 8 12
12 20
32
And the input and output would be like this,
lastnum([0 1 2 3 4])
ans = 32
I mean... is there any progresses that I can do??? You may not understand but, the reverse triangle above can guide you about my question.
I also tagged MATLAB since it has similar language. MATLAB pros may help my problem.
Notice that the number of times each element gets added to produce the final result comes from Pascals triangle itself, so, e.g., for the vector [a b c d] the result will be a+3b+3c+d. So create a vector of entries in Pascals triangle and multiply and add with the original vector v.
I only have access to Matlab, Octave may not have all these functions.
This is a one-liner diag(fliplr(pascal(numel(v)))).'*v(:).
Or a looping version
s = 0;
for i = 0:numel(v)-1
s = s+nchoosek(numel(v)-1,i)*v(i+1);
end
s
Simplest thing I can think of is:
while length(x) > 0
disp(x)
x = x(1:end-1) + x(2:end);
end
or did I misunderstand the question?
Here is the version for both MATLAB and Octave:
function y = lastnum(v)
while 1
if length(v) == 2
y = sum(v)
break;
end
# disp(v); # if you want to print the progress
vt = [];
for k = 1:(length(v)-1)
vt(end+1) = sum(v(k:(k+1)));
end
v = vt;
end
end

matlab: sum of f(k_i,x) where k_i are scalars and x is a matrix

Any idea how to formulate this sum other than using a loop?
sum(i) f(k(i),x) where k_i are some entries of a vector and x is a matrix.
Currently what I'm doing is this, but I'd rather have a general solution:
for ii=1:length(k)
psi=psi+f(k(ii),x)
end
If it's any concern:
f(k,x)=g(k)*exp(k*x)
Assuming g can take a vector input and returns a vector result of the same size, and that x is just a scalar
f=#(k,x) g(k).*exp(k*x);
psi=sum(f(k,x))
or if g can't be or isn't able to take vector input, you can do
g=#(k) arrayfun(g,k);
and then define f as before.
Do you mean that you want to sum only specific rows?
If so, this will do it:
a= [1 2 3 4;
5 2 7 2;
0 0 2 3];
k= [1 3]; %rows selection for sum
result= sum(a(k,:))

How to add vectors of different length in MATLAB

I'm trying to do the following:
Let's say I have:
x1=[7];
x2=[3 4];
x3=[1 -1 5];
x4=[2 5 -1 3];
and I want to add them together.
I know it's not possible to add vectors of different dimensions, but what I'm trying to achieve is a new vector having:
v=[2 5+1 -1-1+3 3+5+4+7];
I tried to pad the relevant vectors with zeros, to get:
x1=[0 0 0 7];
x2=[0 0 3 4];
x3=[0 1 -1 5];
x4=[2 5 -1 3];
and then the addition will be natural, but couldn't find a way to do it.
Of course, I'm looking for an iterative method of doing that, meaning, every vector xi is the result of the i'th iteration, where the number of iterations, n, is known in advance. (in the above example n=4)
My first thought would be something like
x1 = [zeros(1, 4 - length(x1)) x1];
Where you would substitute max(all_your_arrays) for 4 in the above line. If your arrays are in cell arrays you should be able to easily adapt that to a loop.

vectorizing histogram on matrix rows in matlab

Hello I need to calculate a histogram for every row in a big matrix.
For the first row for example I get this:
AA = hist(symbolic_data(1,:), 1:8);
With symbolic_data(1,:)=[7 6 7 8 7], I get AA=[0 0 0 0 0 1 3 1].
Of course this is easy using a simple for loop, but my symbolic_data matrix is really big.
Is there a way to vectorize this.
I've been fiddling with bsxfun, but I can't make it work.
Any help would be much appreciated.
Thanks for your time.
From Matlab help:
N = hist(Y) bins the elements of Y into 10 equally spaced containers
and returns the number of elements in each container. If Y is a
matrix, hist works down the columns.
so:
AA = hist(symbolic_data', 1:8);
will do what you want
The answer by #Mercury is the way to go. But if you want to do it with bsxfun:
If you only have integer values, use
bin_centers = 1:8;
AA = squeeze(sum(bsxfun(#eq, permute(symbolic_data,[2 3 1]), bin_centers(:).')));
If the values are not necessarily integer:
bin_centers = 1:8;
AA = squeeze(sum( bsxfun(#le, permute(symbolic_data,[2 3 1]), bin_centers(:).'+.5) &...
bsxfun(#gt, permute(symbolic_data,[2 3 1]), bin_centers(:).'-.5) ));

Matlab Vectorization : How to remove for loop in this?

I have following matrices :
X=1 2 3
A=1 2 3
4 5 6
7 8 9
I Want to do
for each (i,j) in A
B(i,j) = sum(A(i,j)*x)
i.e. each element of A is multiplied by vector X, and we sum all 3 elements of that vector.
Can it be done without for loop ?
Something like this perhaps ?
B = A.*sum(X)
EDIT As #HighPerformanceMark points out, you can simply multiply by the sum of X, which is clearly preferrable. Below is a solution that does exactly the steps you wanted to do, which may make my solution useful for non-linear variants of the problem.
You can turn X into a 1-by-1-by-3 array, and multiply it with A to get a 3-by-3-by-3 array, which you can then sum along the third dimension:
X = permute(X,[1,3,2]); %# make X 1*1*3
B = sum( bsxfun(#times, A, X), 3); %# multiply and sum