Store and plot two structures in MATLAB - matlab

I am working with structures that two of which are shown below; A and B. I need to store A and B in a way (possibly not using tables) that allows MATLAB to plot them similar to the images.

In my viewpoint, generating a sparse matrix and store the circles in it may be a solution. Here is a function which could generate a circle array in a sparse matrix with given structure & color. What you need is design a table which denotes the color of each item (0 means there a nothing in that position).
Function CircleArrays.m
function [Imgout] = CircleArrays(DataIn,r,s)
%%Draw a circle array with given colors
% Parameters:
% DataIn ---- structures & color
% r ---- the radius of each circle
% s ---- the sparsity of the data
% Demo:
% S=rand(10);
% r=20;
% sparsity=1;
% Img=CircleArrays(S,r,sparsity);
% figure()
% colormap(hot)
% imagesc(1-Img)
% axis equal
% axis off
%Define a pre-allocate sparse matrix
[m,n]=size(DataIn);
Imgout=spalloc(m*(2*r+1),n*(2*r+1),floor(n*(2*r+1)*m*(2*r+1)*s));
%Create the Mask
I = 1:(2*r+1); % Define the x and y coordinates of the basic mask
x = (I - r)-1;
y = (r - I)+1;
[X,Y] = meshgrid(x,y); % Create the mask
M = (X.^2 + Y.^2 <= r^2);
[xx,yy]=ind2sub(size(M),find(M == true));
%%Add circles into the matrix
for ii=1:m
for jj=1:n
if (DataIn(ii,jj) == 0)
continue;
else
MidX=(ii-1)*(2*r+1)+r+1;
MidY=(jj-1)*(2*r+1)+r+1;
Imgout(sub2ind(size(Imgout),MidX+xx-r-1,MidY+yy-r-1))=DataIn(ii,jj);
end
end
end
end
DEMO:
clc; clear;
%%Structures & configs
% define structures & color
S=[0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 .6 0.6 .6 .6 .6 .6 .6 .6 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 1 0 0 0 0 0 0 1 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;];
%set the radius of each circle and the sparsity of the data
r=20;
sparsity=0.25;
%generate the Structures
Img=CircleArrays(S,r,sparsity);
%%Draw the picture
figure()
colormap(hot)
imagesc(1-Img)
axis equal
axis off
output by DEMO code:
output by DEMO code in the function:
Notes: I wrote this function based on one of my old answers, so the circle mask maybe not 100% perfect, you can change it to whatever you like.

Related

MATLAB surface from rotated closed curves

Essentially I am trying to create a volume by rotating a closed curve. I have attempted to use cylinder to achieve this, but I am getting undesirable results. I also have tried directly using surf. Here are those two attempts (newEl defined below).
elPatternPlot = plot3(newEl(:,1),newEl(:,2),newEl(:,3),'gr-','LineWidth',0.5);
xlabel('x')
ylabel('y')
zlabel('z')
grid on
Next, I rotate the 2D closed curve to the correct angle.
rotate(elPatternPlot, [1 0 0], 90);
To generate data points in the desired volume, I use rotate:
% Now rotate around z and store in the data
axObjs = azElFig.Children;
dataObjs = axObjs.Children;
xElData = dataObjs(1).XData;
yElData = dataObjs(1).YData;
zElData = dataObjs(1).ZData;
for a1=1:5:180
rotate(elPatternPlot, [0 0 1], a1);
axObjs = azElFig.Children;
dataObjs = axObjs.Children;
xElData = [xElData dataObjs(1).XData];
yElData = [yElData dataObjs(1).YData];
zElData = [zElData dataObjs(1).ZData];
end
plot3(xElData,yElData,zElData,'r-','LineWidth',0.5)
And the result:
This this yields the correct outside geometry, but I am seeking to create a volume. From here I use surf:
xv = linspace(min(xElData), max(xElData), 150);
yv = linspace(min(yElData), max(yElData), 150);
[X, Y] = meshgrid(xv, yv);
Z = griddata(xElData,yElData,zElData,X,Y);
figure; surf(X,Y,Z);
The output is:
Using cylinder,
[x,y,z] = cylinder(Z);
figure; surf(x,y,z)
I obtain:
The desired surface should look more like (from the bottom):
And from the side, a filled in version of this:
newEl =
-906.5000 -36.5000 0
-909.5000 -65.5000 0
-903.5000 -91.5000 0
-891.5000 -139.5000 0
-877.5000 -203.5000 0
-863.5000 -238.5000 0
-855.5000 -254.5000 0
-847.5000 -269.5000 0
-839.5000 -284.5000 0
-784.5000 -369.5000 0
-771.5000 -384.5000 0
-746.5000 -406.5000 0
-733.5000 -421.5000 0
-695.5000 -457.5000 0
-668.5000 -479.5000 0
-641.5000 -496.5000 0
-614.5000 -513.5000 0
-600.5000 -525.5000 0
-573.5000 -544.5000 0
-561.5000 -549.5000 0
-549.5000 -553.5000 0
-488.5000 -579.5000 0
-474.5000 -585.5000 0
-460.5000 -592.5000 0
-446.5000 -599.5000 0
-417.5000 -603.5000 0
-388.5000 -607.5000 0
-293.5000 -611.5000 0
-277.5000 -608.5000 0
-246.5000 -597.5000 0
-231.5000 -593.5000 0
-187.5000 -578.5000 0
-160.5000 -553.5000 0
-133.5000 -528.5000 0
-120.5000 -512.5000 0
-85.5000 -478.5000 0
-61.5000 -428.5000 0
-56.5000 -411.5000 0
-47.5000 -359.5000 0
-42.5000 -342.5000 0
-33.5000 -289.5000 0
-28.5000 -271.5000 0
-19.5000 -220.5000 0
-14.5000 -202.5000 0
-5.5000 -149.5000 0
-0.5000 -132.5000 0
4.5000 -128.5000 0
9.5000 -161.5000 0
18.5000 -194.5000 0
23.5000 -226.5000 0
32.5000 -261.5000 0
37.5000 -293.5000 0
42.5000 -324.5000 0
51.5000 -359.5000 0
56.5000 -390.5000 0
65.5000 -426.5000 0
70.5000 -455.5000 0
125.5000 -517.5000 0
138.5000 -528.5000 0
165.5000 -556.5000 0
178.5000 -567.5000 0
192.5000 -578.5000 0
207.5000 -585.5000 0
251.5000 -596.5000 0
267.5000 -604.5000 0
298.5000 -611.5000 0
393.5000 -607.5000 0
422.5000 -602.5000 0
451.5000 -597.5000 0
465.5000 -592.5000 0
479.5000 -586.5000 0
493.5000 -580.5000 0
530.5000 -565.5000 0
542.5000 -559.5000 0
554.5000 -552.5000 0
592.5000 -534.5000 0
619.5000 -515.5000 0
646.5000 -496.5000 0
673.5000 -477.5000 0
725.5000 -430.5000 0
738.5000 -419.5000 0
776.5000 -379.5000 0
789.5000 -368.5000 0
801.5000 -353.5000 0
811.5000 -336.5000 0
836.5000 -292.5000 0
844.5000 -279.5000 0
852.5000 -268.5000 0
860.5000 -253.5000 0
881.5000 -200.5000 0
886.5000 -184.5000 0
891.5000 -167.5000 0
895.5000 -146.5000 0
902.5000 -104.5000 0
907.5000 -90.5000 0
909.5000 -46.5000 0
904.5000 6.5000 0
899.5000 58.5000 0
897.5000 60.5000 0
875.5000 126.5000 0
867.5000 142.5000 0
828.5000 208.5000 0
820.5000 224.5000 0
763.5000 276.5000 0
750.5000 289.5000 0
712.5000 319.5000 0
699.5000 332.5000 0
686.5000 341.5000 0
659.5000 360.5000 0
632.5000 378.5000 0
605.5000 396.5000 0
578.5000 416.5000 0
566.5000 431.5000 0
517.5000 496.5000 0
505.5000 509.5000 0
436.5000 567.5000 0
407.5000 587.5000 0
377.5000 603.5000 0
361.5000 604.5000 0
345.5000 606.5000 0
329.5000 607.5000 0
313.5000 608.5000 0
282.5000 610.5000 0
236.5000 606.5000 0
221.5000 601.5000 0
151.5000 567.5000 0
111.5000 547.5000 0
100.5000 533.5000 0
89.5000 520.5000 0
79.5000 500.5000 0
60.5000 477.5000 0
46.5000 454.5000 0
27.5000 427.5000 0
13.5000 403.5000 0
-10.5000 403.5000 0
-24.5000 423.5000 0
-38.5000 444.5000 0
-52.5000 465.5000 0
-66.5000 486.5000 0
-75.5000 502.5000 0
-96.5000 531.5000 0
-107.5000 548.5000 0
-147.5000 566.5000 0
-174.5000 581.5000 0
-202.5000 591.5000 0
-217.5000 600.5000 0
-262.5000 611.5000 0
-309.5000 607.5000 0
-325.5000 607.5000 0
-341.5000 606.5000 0
-357.5000 604.5000 0
-373.5000 603.5000 0
-403.5000 587.5000 0
-432.5000 566.5000 0
-501.5000 511.5000 0
-513.5000 494.5000 0
-525.5000 478.5000 0
-537.5000 463.5000 0
-587.5000 407.5000 0
-628.5000 380.5000 0
-655.5000 361.5000 0
-682.5000 341.5000 0
-708.5000 320.5000 0
-721.5000 311.5000 0
-759.5000 277.5000 0
-797.5000 244.5000 0
-807.5000 237.5000 0
-816.5000 224.5000 0
-824.5000 213.5000 0
-832.5000 199.5000 0
-871.5000 124.5000 0
-882.5000 104.5000 0
-887.5000 98.5000 0
-894.5000 72.5000 0
-896.5000 37.5000 0
-899.5000 34.5000 0
-901.5000 1.5000 0
-906.5000 -36.5000 0
You almost had it right. The problem is within how you rotate inside the for loop.
Your code:
for a1=1:5:180
rotate(elPatternPlot, [0 0 1], a1);
...
end
a1 is incremented by 5 as it iterates. Therefore, you are not rotating it by a step of 5.
To fix this, simply change
rotate(elPatternPlot, [0 0 1], a1);
to
rotate(elPatternPlot, [0 0 1], 5);
To make it easier to plot your figures, you can keep your data in matrix form:
for a1=1:5:180
rotate(elPatternPlot, [0 0 1], 5);
xElData = [xElData; elPatternPlot.XData];
yElData = [yElData; elPatternPlot.YData];
zElData = [zElData; elPatternPlot.ZData];
end
To plot:
figure
plot3(xElData, yElData, zElData)
grid on; axis equal
figure
surf(xElData, yElData, zElData)
grid on; axis equal
figure
mesh(xElData, yElData, zElData)
grid on; axis equal

bit error rate calculation 15,11 hamming code graph

Below, in my code is supposes to find the simulation BER. But I am getting error on this code where nErrors = biterr(dataIn,dataDec2) this line gives matrix dimensions mismatch.
Is there anyone who can help me in this??
close all;
clear all;
M = 2; % Modulation order
k = log2(M); % Bits per symbol
EbNoVec = -4:2:0; % Eb/No values (dB)
No = -10;
numSymPerFrame = 100; % Number of PSK symbols per frame
berEst2 = zeros(size(EbNoVec));
G2=[1 1 0 0 1 0 0 0 0 0 0 0 0 0 0;
0 1 1 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 1 1 0 0 1 0 0 0 0 0 0 0 0;
1 0 1 0 0 0 0 1 0 0 0 0 0 0 0;
1 0 0 1 0 0 0 0 1 0 0 0 0 0 0;
0 1 0 1 0 0 0 0 0 1 0 0 0 0 0;
1 1 1 0 0 0 0 0 0 0 1 0 0 0 0;
0 1 1 1 0 0 0 0 0 0 0 1 0 0 0;
1 0 1 1 0 0 0 0 0 0 0 0 1 0 0;
1 1 0 1 0 0 0 0 0 0 0 0 0 1 0;
1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 ];
H2= gen2par(G2);
decoding2 = syndtable(H2);
Pt2 = zeros(size(EbNoVec));
for n = 1:length(EbNoVec)
% Convert Eb/No to SNR
snrdB = EbNoVec(n) + 10*log10(15/11);
% Reset the error and bit counters
numErrs = 0;
numBits = 0;
Pt2(n)= 10^((snrdB-10)/10);
while numErrs < 100
% Generate binary data and convert to symbols
dataIn = randi([0 1],numSymPerFrame,k)
dataSym = bi2de(dataIn)
dataEnc2 = encode(dataIn,15,11,'linear/binary',G2)
% PSK modulation
txSig = pskmod(dataEnc2,M);
% Pass through AWGN channel
rxSig = awgn(txSig,snrdB,'measured');
% Demodulate the noisy signal
rxSym = pskdemod(rxSig,M);
% Convert received symbols to bits
dataOut = de2bi(rxSym,k);
dataDec2 =decode(rxSym,15,11,'linear/binary',G2, decoding2);
% Calculate the number of bit errors
nErrors = biterr(dataIn,dataDec2);
% Increment the error and bit counters
numErrs = numErrs + nErrors;
numBits = numBits + numSymPerFrame*k;
end
% Estimate the BER
berEst2(n) = numErrs/numBits;
end
berTheory2 = berawgn(EbNoVec,'psk',M,'nondiff');
hold on
semilogy(EbNoVec,berEst1,'r','LineWidth',2);
I debugged your code with a breakpoint on Line 46 [nErrors = biterr(dataIn,dataDec2)]. It seems the dataIn array is 100 x 1 and dataDec2 is a 110 x 1 array. 'biterr' function calculates the number of places where the two vectors of equal length differ.
This will give you a better explanation.
https://www.mathworks.com/help/comm/ref/biterr.html

To print the n nodes of maximum degree with Matlab

I need a matlab script that is going to return the n nodes of maximum degree in a graph.
For exemple:
N = maxnodes(Graph,n)
Graph is a matrix
n the number of nodes that we need
N is a vector that conatains the n nodes.
Here is my source code (script). But it doesn't work well.
M = [0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0;
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0;
0 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0;
1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0;
0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0;
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1;
0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0;
0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0;
0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0;
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0;
0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1;
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0;];
n = 5; % The number of nodes that we want
G=[]; % I'll store here the n nodes of maximum degree
for i=1:size(M)
G1(1,i)=sum(M(i,:)); % I'm storing each node with its degree in G1
G1(2,i)=i;
C(1,i)=G1(1,i); %I store only degree of nodes
end
C1 = sort(C,'descend'); % I sort "descendly" the degrees of nodes
for i=1:n %We want to take only the n nodes that we need and save it in C2
C2(1,i) = C1(1,i);
end
C2; % This vector stores the n descend maximum degrees that I need.
%My actual problem is here. How could I find the node that correspond to each degree?
%I tried to do it with the following loop:
for j=1:n
for i=1:size(M)
if C2(1,j) == G1(1,i)
G2(1,j)=G1(2,i);
end
end
end %But this loop doesn't store well the nodes in G2 because it repeats nodes.
G2
You have absolutely shown no effort so you actually shouldn't be getting any help from anyone.... but I love graph problems, so I'll throw you a bone.
I'm going to assume that Graph is an adjacency matrix, where each element (i,j) in the matrix corresponds to an edge connected between the two nodes i and j. I also am assuming that you have an undirected graph as input. If you examine the nature of the adjacency matrix (that Wikipedia article has a great example), it's not hard to see that the degree of a node i is simply the sum over all of the columns of row i in the adjacency matrix. Recall that the degree is defined as the total number of edges connected to a particular node. As such, all you have to do is sum over all of the columns for each row, and determine the rows that have the largest degree in your graph. Once we do this, we simply return the nodes that have this largest degree, which is up to n.
However, we will put in a safeguard where if we specify n to be larger than number of nodes having this maximum degree, we will cap it so that we only show up to this many nodes rather than n.
Therefore:
function [N] = maxnodes(Graph, n)
%// Find degrees of each node
degs = sum(Graph, 2);
%// Find those nodes that have the largest degree
locs = find(degs == max(degs));
%// If n is larger than the total number of nodes
%// having this maximum degree, then cap it
if n > numel(locs)
n = numel(locs);
end
%// Return those nodes that have this maximum degree
N = locs(1:n);
Here is a script that works very well and solves my problem. Otherwise, I would have liked well that my source code above would be debug.
function N = maxnodes(M,n)
nb1_rows= sum(M,2);
[nbs,is] = sort(nb1_rows,'descend');
N = transpose(is(1:n));

Drawing a line of ones on a matrix

I have a matrix m = zeros(1000, 1000). Within this matrix I want to draw an estimate of the line which passes through 2 points from my matrix. Let's say x = [122 455]; and y = [500 500];.
How can I do this in Matlab? Are there any predefined functions to do this? I am using Matlab 2012b.
I'll denote the two endpoints as p1 and p2 because I'm planning to use x and y for something else. I'm also assuming that the first coordinate of p1 and p2 is x and the second is y. So here's a rather simple way to do it:
Obtain the equation of the line y = ax + b. In MATLAB, this can be done by:
x = p1(1):p2(1)
dx = p2(1) - p1(1);
dy = p2(2) - p1(2);
y = round((x - p1(1)) * dy / dx + p1(2));
Convert the values of x and y to indices of elements in the matrix, and set those elements to 1.
idx = sub2ind(size(m), y, x);
m(idx) = 1;
Example
Here's an example for a small 10-by-10 matrix:
%// This is our initial conditon
m = zeros(10);
p1 = [1, 4];
p2 = [5, 7];
%// Ensure the new x-dimension has the largest displacement
[max_delta, ix] = max(abs(p2 - p1));
iy = length(p1) - ix + 1;
%// Draw a line from p1 to p2 on matrix m
x = p1(ix):p2(ix);
y = round((x - p1(ix)) * (p2(iy) - p1(iy)) / (p2(ix) - p1(ix)) + p1(iy));
m(sub2ind(size(m), y, x)) = 1;
m = shiftdim(m, ix > iy); %// Transpose result if necessary
The result is:
m =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Update: I have patched this algorithm to work when dy > dx by treating the dimension with the largest displacement as if it were the x-dimension, and then transposing the result if necessary.
Neither of the provided answers work for displacements in y greater than in x (dy > dx).
As pointed out, Bresenham's line algorithm is exactly meant for that.
The matlab file provided here works similarly than the examples provided in the other answers but covers all the use-cases.
To relate to the previously provided example, the script can be used like this:
% initial conditions
m = zeros(10);
p1 = [1, 4];
p2 = [5, 10];% note dy > dx
% use file provided on file exchange
[x y] = bresenham(p1(1),p1(2),p2(1),p2(2));
% replace entries in matrix m
m(sub2ind(size(m), y, x)) = 1;
result looks like this:
m =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
For me (matlab R2013b) following line did not work, when p1(1)>p2(2) (":" can not count backwards):
x = p1(1):p2(1);
E.G.:
1:10
1 2 3 4 5 6 7 8 9 10
10:1
Empty matrix: 1-by-0
But it worked when I used linspac instead:
x = linspace(p1(1), p2(1), abs(p2(1)-p1(1))+1);

bicubic interpolation of 3D surface

I am writing an algorithm in matlab to for bicubic interpolation of a surface Psi(x,y). I have a bug in the code and cannot seem to track it down. I am trying a test case with Psi=X^2-0.25 so that its easier to track down the bug. It seems as if my interpolation has an offset. My comments are included in my code. Any help would be appreciated.
Plot of Psi=X^2 in blue and interpolation in red
Countour lines of Psi are plotted and the red dot is the point I am computing the interpolation about. The thick red line is the interpolation which is offset quite a bit from the red dot.
function main()
epsilon=0.000001;
xMin=-1+epsilon;
xMax= 1+epsilon;
yMin=-1+epsilon;
yMax= 1+epsilon;
dx=0.1; Nx=ceil((xMax-xMin)/dx)+1;
dy=0.1; Ny=ceil((yMax-yMin)/dy)+1;
x=xMin:dx:xMax; x=x(1:Nx);
y=yMin:dy:yMax; y=y(1:Ny);
[XPolInX,XPolInY]=GetGhostMatricies(Nx,Ny); %Linear extrapolation matrix
[D0x,D0y]=GetDiffMatricies(Nx,Ny,dx,dy); %derivative matricies: D0x is central differencing in x
[X,Y]=meshgrid(x,y);
Psi=X.^2-0.25; %Note that my algorithm is being written for a Psi that may not have a analytic representation. This Psi is only a test case.
psi=zeros(Nx+2,Ny+2); %linearly extrapolate psi (for solving differential equation not shown here)
psi(2:(Nx+1),2:(Ny+1))=Psi';
psi=(XPolInY*(XPolInX*psi)')';
%compute derivatives of psi
psi_x =D0x*psi; psi_x =(XPolInY*(XPolInX*psi_x)')';
psi_y =(D0y*psi')'; psi_y =(XPolInY*(XPolInX*psi_y)')';
psi_xy=D0x*psi_y; psi_xy=(XPolInY*(XPolInX*psi_xy)')';
% i have verified that my derivatives are computed correctly
biCubInv=GetBiCubicInverse(dx,dy);
i=5; %lets compute the bicubic interpolation at this x(i), y(j)
j=1;
psiVoxel=[psi( i,j),psi( i+1,j),psi( i,j+1),psi( i+1,j+1),...
psi_x( i,j),psi_x( i+1,j),psi_x( i,j+1),psi_x( i+1,j+1),...
psi_y( i,j),psi_y( i+1,j),psi_y( i,j+1),psi_y( i+1,j+1),...
psi_xy(i,j),psi_xy(i+1,j),psi_xy(i,j+1),psi_xy(i+1,j+1)]';
a=biCubInv*psiVoxel; %a=[a00 a01 ... a33]; polynomial coefficients; 1st index is power of (x-xi), 2nd index is power of (y-yj)
xi=x(5); yj=y(1);
clear x y
x=(xi-.2):.01:(xi+.2); %this is a local region about the point we are interpolating
y=(yj-.2):.01:(yj+.2);
[dX,dY]=meshgrid(x,y);
Psi=dX.^2-0.25;
figure(2) %just plotting the 0 level contour of Psi here
plot(xi,yj,'.r','MarkerSize',20)
hold on
contour(x,y,Psi,[0 0],'r','LineWidth',2)
set(gca,'FontSize',14)
axis([x(1) x(end) y(1) y(end)])
grid on
set(gca,'xtick',(xi-.2):.1:(xi+.2));
set(gca,'ytick',(yj-.2):.1:(yj+.2));
xlabel('x')
ylabel('y')
[dX dY]=meshgrid(x-xi,y-yj);
%P is my interpolating polynomial
P = a(1) + a(5) *dY + a(9) *dY.^2 + a(13) *dY.^3 ...
+ a(2)*dX + a(6)*dX .*dY + a(10)*dX .*dY.^2 + a(14)*dX .*dY.^3 ...
+ a(3)*dX.^2 + a(7)*dX.^2.*dY + a(11)*dX.^2.*dY.^2 + a(15)*dX.^2.*dY.^3 ...
+ a(4)*dX.^3 + a(8)*dX.^3.*dY + a(12)*dX.^3.*dY.^2 + a(16)*dX.^3.*dY.^3 ;
[c h]=contour(x,y,P)
clabel(c,h)
figure(3)
plot(x,x.^2-.25) %this is the exact function
hold on
plot(x,P(1,:),'-r*')
%See there is some offset here
end
%-------------------------------------------------------------------------
function [XPolInX,XPolInY]=GetGhostMatricies(Nx,Ny)
XPolInX=diag(ones(1,Nx+2),0);
XPolInY=diag(ones(1,Ny+2),0);
XPolInX(1,1) =0; XPolInX(1,2) =2; XPolInX(1,3) =-1;
XPolInY(1,1) =0; XPolInY(1,2) =2; XPolInY(1,3) =-1;
XPolInX(Nx+2,Nx+2)=0; XPolInX(Nx+2,Nx+1)=2; XPolInX(Nx+2,Nx)=-1;
XPolInY(Ny+2,Ny+2)=0; XPolInY(Ny+2,Ny+1)=2; XPolInY(Ny+2,Ny)=-1;
fprintf('Done GetGhostMatricies\n')
end
%-------------------------------------------------------------------------
function [D0x,D0y]=GetDiffMatricies(Nx,Ny,dx,dy)
D0x=diag(ones(1,Nx-1),1)-diag(ones(1,Nx-1),-1);
D0y=diag(ones(1,Ny-1),1)-diag(ones(1,Ny-1),-1);
D0x(1,1)=-3; D0x(1,2)=4; D0x(1,3)=-1;
D0y(1,1)=-3; D0y(1,2)=4; D0y(1,3)=-1;
D0x(Nx,Nx)=3; D0x(Nx,Nx-1)=-4; D0x(Nx,Nx-2)=1;
D0y(Ny,Ny)=3; D0y(Ny,Ny-1)=-4; D0y(Ny,Ny-2)=1;
%pad with ghost cells which are simply zeros
tmp=D0x; D0x=zeros(Nx+2,Nx+2); D0x(2:(Nx+1),2:(Nx+1))=tmp; tmp=0;
tmp=D0y; D0y=zeros(Ny+2,Ny+2); D0y(2:(Ny+1),2:(Ny+1))=tmp; tmp=0;
%scale appropriatley by dx & dy
D0x=D0x/(2*dx);
D0y=D0y/(2*dy);
end
%-------------------------------------------------------------------------
function biCubInv=GetBiCubicInverse(dx,dy)
%p(x,y)=a00+a01(x-xi)+a02(x-xi)^2+...+a33(x-xi)^3(y-yj)^3
%biCubic*a=[psi(i,j) psi(i+1,j) psi(i,j+1) psi(i+1,j+1) psi_x(i,j) ... psi_y(i,j) ... psi_xy(i,j) ... psi_xy(i+1,j+1)]
%here, psi_x is the x derivative of psi
%I verified that this matrix is correct by setting dx=dy=1 and comparing to the inverse here http://en.wikipedia.org/wiki/Bicubic_interpolation
biCubic=[
%00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 dx dx^2 dx^3 0 0 0 0 0 0 0 0 0 0 0 0;
1 0 0 0 dy 0 0 0 dy^2 0 0 0 dy^3 0 0 0;
1 dx dx^2 dx^3 dy dx*dy dx^2*dy dx^3*dy dy^2 dx*dy^2 dx^2*dy^2 dx^3*dy^2 dy^3 dx*dy^3 dx^2*dy^3 dx^3*dy^3;
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 2*dx 3*dx^2 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 0 0 0 dy 0 0 0 dy^2 0 0 0 dy^3 0 0;
0 1 2*dx 3*dx^2 0 dy 2*dx*dy 3*dx^2*dy 0 dy^2 2*dx*dy^2 3*dx^2*dy^2 0 dy^3 2*dx*dy^3 3*dx^2*dy^3;
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 1 dx dx^2 dx^3 0 0 0 0 0 0 0 0;
0 0 0 0 1 0 0 0 2*dy 0 0 0 3*dy^2 0 0 0;
0 0 0 0 1 dx dx^2 dx^3 2*dy 2*dx*dy 2*dx^2*dy 2*dx^3*dy 3*dy^2 3*dx*dy^2 3*dx^2*dy^2 3*dx^3*dy^2;
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 1 2*dx 3*dx^2 0 0 0 0 0 0 0 0;
0 0 0 0 0 1 0 0 0 2*dy 0 0 0 3*dy^2 0 0;
0 0 0 0 0 1 2*dx 3*dx^2 0 2*dy 4*dx*dy 6*dx^2*dy 0 3*dy^2 6*dx*dy^2 9*dx^2*dy^2];
biCubInv=inv(biCubic);
end
%-------------------------------------------------------------------------
I found my error. I pad my matricies with ghost cells, however I forget that now the i in Psi without ghost cells is i+1 in psi with ghost cells. Hence, I should be evaluating my interpolating polynomial P at xi=x(6); yj=y(2), not xi=x(5); yj=y(1).