I have created a planar piecewise biarc curve in MATLAB using the rscvn function. I have been able to plot it as follows:
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p)
fnplt(B)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
Unfortunately I can't for the life of me figure out how to evaluate the function B for an arbitrary position, say 2.6.
How should I attempt this in MATLAB?
You can evaluate a function from the curve fitting toolbox using the fnval function.
See https://www.mathworks.com/help/curvefit/fnval.html
Example code
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p);
fnval(B,2.6)
Output
ans =
1.8526
5.1884
Edit From your comment and the format of your data I assume you are actually looking to estimate a continuous function from your data. In that case you can use.
p = [0 1 2 3; 2 6 3 9];
C = csapi(p(1,:), p(2,:));
fnplt(C)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
fnval(C,2.6)
Output
ans =
4.4960
Related
Suppose I have 2 vectors, data vector:
x=[2 1 2 1]
and weights vector
y=[1 2 3]
I want Matlab to convolve these vectors in sense of 1D neural network, i.e. run y as window against x and compute convolutions:
If I run built-in function conv then I get
>> conv(x,y)
ans =
2 5 10 8 8 3
which contains correct values in the middle but has something unknown at margins. Manual for conv function looks completely different with what I want.
If I run
>> conv(x,y, 'same')
ans =
5 10 8 8
I also get something strange.
You were very close to solving it by specifying the 3rd input to conv, but instead of 'same' you should've used 'valid':
x = [2 1 2 1];
y = [1 2 3];
conv(x,y,'valid')
ans =
10 8
Just reverse the filter:
x = [2,1,2,1];
y = [1,2,3];
z = conv(x,flip(y),'valid');
Is there an equivalent function for tuples in Matlab as there is for Mathematica?
See the first example:
http://reference.wolfram.com/language/ref/Tuples.html
I just mean the outputs and not necessarily the braces.
Thank you.
As I stated in comments, you only need to adapt this answer. You can do it as follows:
function y = tuples(x, n)
y = cell(1,n);
[y{end:-1:1}] = ndgrid(x);
y = cat(n+1, y{:});
y = reshape(y, [], n);
This gives a matrix where each row is a tuple. For example:
>> tuples([1 2 5], 2)
ans =
1 1
1 2
1 5
2 1
2 2
2 5
5 1
5 2
5 5
I have two matrix as
A = [1 2 3; 4 6 7; 3 6 7]
B = [2 5 6; 2 8 7; 2 8 5]
I want to plot a graph between this two matrix, I mean in such as way that A(1,1) as x coordinate and B(1,1) as Y coordinate of 1st point. Similarly, for 2nd point A(1,2) as x and B(1,2) as Y and so on. At last I should get straight line connecting this point for each row.
And then I have the measure the length of the line connecting all the points for each row, so that I can know which row have greater length
I tried this
for i=1:1:3
plot(A(i,:),B(i,:)), hold on;
end
Is it correct because I can't able to interpret and how to measure the length also??
Your way of plotting seems correct.
To calculate the length of each line I would use this code:
for i=1:1:3
len(i) = sum(sqrt(diff(A(i,:),1).^2+diff(B(i,:)).^2));
end
You don't need for loop to plot. Just do.
A = [1 2 3; 4 6 7; 3 6 7];
B= [2 5 6; 2 8 7; 2 8 5];
% Plot lines
plot(A.',B.');
% Calculate length of lines
length=sum(sqrt((diff(A,1,2).^2)+(diff(B,1,2).^2)),2);
I am trying to replicate the Kron product using only repmat and reshape and I believe I am pretty close but I can't manage to do the last correct reshape.
Particularly I have problem in reshaping A
To make things simple let suppose we have
A=[1 3; 2 4]
B=[5 10; 10 5]
so my kron(A,B) is going to be a 4x4 matrix.
kron=[5 10 15 30
10 5 30 15
10 20 20 40
20 10 40 20]
I am proceeding this way:
Y=repmat(B,2,2)
X=A(:);
X=repmat(X,1,2)';
X=X(:);
X=repmat(X,1,2);
which gives me the following 8x2 Matrix:
X= [1 1
1 1
2 2
2 2
3 3
3 3
4 4
4 4]
I can't just figure out how to do the correct reshape to obtain my 4x4 matrix:
X=[1 1 3 3
1 1 3 3
2 2 4 4
2 2 4 4]
Then I will be able to compute: X.*Y=kron(A,B)
Here's one approach using the powerful trio of bsxfun, permute and reshape -
M = bsxfun(#times,B,permute(A,[3 4 1 2]));
out = reshape(permute(M,[1 3 2 4]),size(A,1)*size(B,1),[]);
If you are hell bent on using repmat, perform the calculation of M with it, like so -
M = repmat(B,[1 1 size(A)]).*permute(repmat(A,[1 1 size(B)]),[3 4 1 2])
Verify output by comparing against kron for generic matrix sizes -
>> A = rand(4,5);
>> B = rand(6,7);
>> M = bsxfun(#times,B,permute(A,[3 4 1 2]));
>> out = reshape(permute(M,[1 3 2 4]),size(A,1)*size(B,1),[]);
>> out_kron = kron(A,B);
>> max(abs(out(:) - out_kron(:)))
ans =
0
Here's one using matrix-multiplication and as such must be pretty efficient -
[mA,nA] = size(A);
[mB,nB] = size(B);
out = reshape(permute(reshape(B(:)*A(:).',mB,nB,mA,nA),[1 3 2 4]),mA*mB,[])
If you don't want to use any loops or bsxfun/arrayfun-solutions, you can do as follows:
[ma,na] = size(A);
[mb,nb] = size(B);
Y = repmat(B,ma,mb);
X = reshape(repmat(reshape(repmat(A(:),1,mb)',ma*mb,na),nb,1),ma*mb,na*nb);
X.*Y
I have two vectors and I want the numbers to follow one each other. By this I mean:
a = [5 6 4 2 1];
b = [4 2 1 3];
Vector b can be smaller than a by one or can be the same length
I want to get
c = [5 4 6 2 4 1 2 3 1];
I tried to use reshape but gave up. So I just implemented the loop.
But is there a better way to solve this problem?
You can use sliced assignment:
% prepare c
c = zeros(1, length(a) + length(b));
% assign a
c(1:2:length(a)*2) = a;
% assign b
c((1:2:length(b)*2)+1) = b;
Note: This solution does not verify if either a or b are too short. Too long a or b will give an error though.
AFAIK reshape is only usable to change the dimensions of a single array/matrix.
Why not use simple concatenation and reordering?
>> a = [5 6 4 2 1];
>> b = [4 2 1 3];
>> c = [a b]; % initialize by concatenation
>> c([1:2:end 2:2:end]) = c % reorder by sliced re-assignment
c =
5 4 6 2 4 1 2 3 1