|
|
@ -310,7 +310,7 @@ void qConvBernstein(const xarray<real, N>& phi, |
|
|
|
bool in = true; |
|
|
|
for (int i = 0; i < halfFaces.size(); ++i) { |
|
|
|
uvector<real, 3> factors(halfFaces[i][0], halfFaces[i][1], halfFaces[i][2]); |
|
|
|
if (prod(factors * x) + halfFaces[i][3] < 0) { |
|
|
|
if (prod(factors * x) + halfFaces[i][3] > 0) { |
|
|
|
in = false; |
|
|
|
break; |
|
|
|
} |
|
|
@ -378,7 +378,7 @@ void testSpherePowerDirectly() |
|
|
|
qConvBernstein(phiBernstein, -1, 1, integrand, 10, {}); |
|
|
|
} |
|
|
|
|
|
|
|
void testCylinderPowerDirectly() |
|
|
|
void testSpherePowerDirectlyByTransformation() |
|
|
|
{ |
|
|
|
// a_x(x-c_x)^2 + a_y(y-c_y)^2 + a_z(x-c_z)^2 - r^2
|
|
|
|
uvector<real, 3> xmin = -1, xmax = 1; |
|
|
@ -388,6 +388,68 @@ void testCylinderPowerDirectly() |
|
|
|
// uvector<real, 3> bias = -k * xmin;
|
|
|
|
uvector<real, 3> k = range; |
|
|
|
uvector<real, 3> bias = xmin; |
|
|
|
real a[3] = {1, 1, 1}; |
|
|
|
real c[3] = {0, 0, 0}; |
|
|
|
real r = 1; |
|
|
|
uvector<int, 3> ext = 3; |
|
|
|
xarray<real, 3> phiPower(nullptr, ext), phiBernstein(nullptr, ext); |
|
|
|
algoim_spark_alloc(real, phiPower, phiBernstein); |
|
|
|
xarrayInit(phiPower); |
|
|
|
xarrayInit(phiBernstein); |
|
|
|
std::vector<std::vector<real>> dimTransformation; |
|
|
|
auto v = xarray2StdVector(phiPower); |
|
|
|
auto vv = xarray2StdVector(phiBernstein); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
uvector<int, 3> idx = 0; |
|
|
|
phiPower.m(idx) += a[dim] * (c[dim]) * (c[dim]); |
|
|
|
idx(dim) = 1; |
|
|
|
phiPower.m(idx) = 2 * a[dim] * (- c[dim]); |
|
|
|
idx(dim) = 2; |
|
|
|
phiPower.m(idx) = a[dim]; |
|
|
|
} |
|
|
|
phiPower.m(0) -= r * r; |
|
|
|
|
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
dimTransformation[0](std::vector<real>(ext(dim), 0)); |
|
|
|
for (int degree = 0; degree < ext(dim); ++degree) { |
|
|
|
// dimTransformation[dim][degree] = 0;
|
|
|
|
const real* binomDegree = Binomial::row(degree); |
|
|
|
for (int i = 0; i <= degree; ++i) { |
|
|
|
// 根据二项定理展开
|
|
|
|
dimTransformation[dim][i] += binomDegree[i] * pow(k(dim), i) * pow(bias(dim), degree - i); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// apply transformation
|
|
|
|
for (auto i = phiPower.loop(); ~i; ++i) { |
|
|
|
real item = phiPower.l(i); |
|
|
|
auto exps = i(); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { item += dimTransformation[dim][exps(dim)]; } |
|
|
|
phiPower.m(i()) = item; |
|
|
|
} |
|
|
|
|
|
|
|
auto integrand = [](const uvector<real, 3>& x) { return 1.0; }; |
|
|
|
power2BernsteinTensorProduct(phiPower, phiBernstein); |
|
|
|
|
|
|
|
v = xarray2StdVector(phiPower); |
|
|
|
uvector<real, 3> testX(0., 0., 0.5); |
|
|
|
real testEval = powerEvaluation(phiPower, testX); |
|
|
|
std::cout << "eval power:" << testEval << std::endl; |
|
|
|
|
|
|
|
real testEvalBernstein = bernstein::evalBernsteinPoly(phiBernstein, testX); |
|
|
|
auto vec = xarray2StdVector(phiBernstein); |
|
|
|
std::cout << "eval bernstein:" << testEval << std::endl; |
|
|
|
qConvBernstein(phiBernstein, -1, 1, integrand, 10, {}); |
|
|
|
} |
|
|
|
|
|
|
|
void testCylinderPowerDirectly() |
|
|
|
{ |
|
|
|
// a_x(x-c_x)^2 + a_y(y-c_y)^2 + a_z(x-c_z)^2 - r^2
|
|
|
|
uvector<real, 3> xmin = -1, xmax = 1; |
|
|
|
uvector<real, 3> range = xmax - xmin; |
|
|
|
assert(all(range != 0)); |
|
|
|
uvector<real, 3> k = range; |
|
|
|
uvector<real, 3> bias = xmin; |
|
|
|
real c[3] = {0, 0, 0}; |
|
|
|
real r = 1, h = 1; |
|
|
|
uvector<int, 3> ext = 3; |
|
|
@ -395,6 +457,7 @@ void testCylinderPowerDirectly() |
|
|
|
algoim_spark_alloc(real, phiPower, phiBernstein); |
|
|
|
xarrayInit(phiPower); |
|
|
|
xarrayInit(phiBernstein); |
|
|
|
std::vector<std::vector<real>> dimTransformation; |
|
|
|
auto v = xarray2StdVector(phiPower); |
|
|
|
auto vv = xarray2StdVector(phiBernstein); |
|
|
|
real top = c[2] + h * 0.5, bottom = c[2] - h * 0.5; |
|
|
@ -407,6 +470,27 @@ void testCylinderPowerDirectly() |
|
|
|
phiPower.m(uvector<int, 3>(1, 0, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(0, 1, 0)) = -bottom * top; |
|
|
|
phiPower.m(uvector<int, 3>(0, 0, 0)) = bottom * top * r * r; |
|
|
|
|
|
|
|
for (int dim = 0; dim < 3; ++dim) { |
|
|
|
dimTransformation.push_back(std::vector<real>(ext(dim), 0)); |
|
|
|
for (int degree = 0; degree < ext(dim); ++degree) { |
|
|
|
// dimTransformation[dim][degree] = 0;
|
|
|
|
const real* binomDegree = Binomial::row(degree); |
|
|
|
for (int i = 0; i <= degree; ++i) { |
|
|
|
// 根据二项定理展开
|
|
|
|
dimTransformation[dim][i] += binomDegree[i] * pow(k(dim), i) * pow(bias(dim), degree - i); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// apply transformation
|
|
|
|
for (auto i = phiPower.loop(); ~i; ++i) { |
|
|
|
real item = phiPower.l(i); |
|
|
|
auto exps = i(); |
|
|
|
for (int dim = 0; dim < 3; ++dim) { item *= dimTransformation[dim][exps(dim)]; } |
|
|
|
phiPower.m(i()) = item; |
|
|
|
} |
|
|
|
|
|
|
|
auto integrand = [](const uvector<real, 3>& x) { return 1.0; }; |
|
|
|
power2BernsteinTensorProduct(phiPower, phiBernstein); |
|
|
|
|
|
|
@ -424,8 +508,8 @@ void testCylinderPowerDirectly() |
|
|
|
integrand, |
|
|
|
50, |
|
|
|
{ |
|
|
|
{0, 0, 1, -bottom}, |
|
|
|
{0, 0, -1, top } |
|
|
|
{0, 0, 1, -top}, |
|
|
|
{0, 0, -1, bottom } |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
@ -474,6 +558,6 @@ void testMain() |
|
|
|
testBooluarray(); |
|
|
|
testMultiPolys(); |
|
|
|
testMultiScale(); |
|
|
|
testSpherePowerDirectly(); |
|
|
|
// testCylinderPowerDirectly();
|
|
|
|
testSpherePowerDirectlyByTransformation(); |
|
|
|
testCylinderPowerDirectly(); |
|
|
|
} |
|
|
|