How do you generate a surface who's value around the origin is within some range

131 Views Asked by At

What's a quick way to generate a smooth, closed-form surface that will be within the range $[0,1]$ for $x, y \in [-1,1]\times[-1,1]$? The surfaces should be of similar complexity to $2\times2$-degree real polynomials.

I tried generating random polynomials and then normalizing them, but then found that the normalization takes a lot of work.

Something like blurred random matrix could be used to fulfill a similar purpose, but the experiment requires that it have a closed form.

2

There are 2 best solutions below

0
On BEST ANSWER

Let $b_0(t), b_1(t), b_2(t)$ be the Bernstein polynomials of degree 2, so ... $$ b_0(t) = (1-t)^2 \\ b_1(t) = 2t(1-t) \\ b_2(t) = t^2 $$ Then take any 9 "height" values $z_{00}, \ldots , z_{22}$ and build the surface $$ S(x,y) = \sum_{i=0}^{2}\sum_{j=0}^{2}z_{ij} b_i\left(\frac{x+1}{2}\right) b_j\left(\frac{y+1}{2}\right) $$ This a second degree polynomial, of course, and it's values lie between $\min z_{ij}$ and $\max z_{ij}$ for $(x,y) \in [-1,1] \times [-1,1]$. So, if you choose all of the $z_{ij}$ to be in the range $[0,1]$, then you'll get what you want.

If you tell me what sorts of shapes you want, I can tell you how to choose the $z$ values.

0
On

===========================================

Edit: It occurred to me that it might make more sense to enlarge a smaller random surface than smoothing a larger one. So, if you want, you can generate the surface z below instead using:

q = rand( ceil( [Ny/My, Nx/Mx] ) );
z = kron( q, ones( ceil( [ Ny, Nx ] ./ size(q) ) ) );
z = z(1:Ny,1:Nx);

===========================================

I don't know if this is what you have in mind, but it will generate a smooth, random surface that lies between zero and one for the given mesh grid of $(x,y)$ values. The vec function below, simply returns a vectorized version of its input, so its definition would look like

function y = vec(x)
y = x(:);
return;

You can change the value of K below to get lower/higher order surfaces.

% The discrete grid we use to define the
% original random surface.
x = (-1 : 0.01 : 1);
y = (-1 : 0.01 : 1)';

% The order of the 2-D polynomial surfce we
% use in the fit.
K = 5;

% The size of the rectangular smooth kernel.
Mx = 5;
My = 5;

% Generate a random surface and smooth it.
Nx = length(x);
Ny = length(y);
s = ones(My,Mx) / (My*Mx);
z = conv2( rand(Ny+My-1,Nx+Mx-1), s, 'valid' );

% Define the polynomial coefficient matrix.
Ncoeffs = (K+1) * (K+2) / 2;
A = zeros( Ny*Nx, Ncoeffs );
cnt = 1;
for kk = 0 : K
  for jj = 0 : kk
    A(:,cnt) = vec( y.^jj * x.^(kk-jj) );
    cnt = cnt + 1;
  end
end

% Solve the normal equations to get the
% polynomial coefficients.
p = ( A' * A ) \ A' * z(:);

% The surface generated by the polynomial.
z_poly = reshape( A * p, [Ny,Nx] );

% Normalize to be between zero and one.
z_surf = z_poly - min( z_poly(:) );
z_surf = z_surf / max( z_surf(:) );

% Display the final surface.
imagesc( z_surf );