Commit 87514d49 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

Merge remote-tracking branch 'INMOST-DEV/master' into fixfc2

# Conflicts:
#	Source/Solver/solver.cpp
#	Source/Solver/solver_bcgsl.hpp
parents fcd37404 0e99faa2
...@@ -41,6 +41,7 @@ bool drawaxis = true, drawcolorbar = true; ...@@ -41,6 +41,7 @@ bool drawaxis = true, drawcolorbar = true;
Element disp_e; Element disp_e;
Mesh::GeomParam table; Mesh::GeomParam table;
ElementArray<Element> orphans; ElementArray<Element> orphans;
int is_material_defined = 0;
#define CLIP_NONE 0 #define CLIP_NONE 0
#define CLIP_NODE 1 #define CLIP_NODE 1
...@@ -55,6 +56,10 @@ ElementArray<Element> orphans; ...@@ -55,6 +56,10 @@ ElementArray<Element> orphans;
Storage::real p[3] = {0,0,0}, n[3] = {0,0,1}; Storage::real p[3] = {0,0,0}, n[3] = {0,0,1};
ElementArray<Element> boundary_faces; ElementArray<Element> boundary_faces;
ElementArray<Edge> added_edges; ElementArray<Edge> added_edges;
std::map<int,std::vector<HandleType> > material_faces;
std::map<int,double> material_x;
std::map<int,double> material_y;
std::map<int,double> material_z;
std::vector<double> harmonic_points, dual_harmonic_points, conormals; std::vector<double> harmonic_points, dual_harmonic_points, conormals;
...@@ -1031,6 +1036,18 @@ class face2gl ...@@ -1031,6 +1036,18 @@ class face2gl
color_t cntcolor; color_t cntcolor;
double cnttexcoord; double cnttexcoord;
public: public:
void shift(double x, double y, double z)
{
cnt[0] += x;
cnt[1] += y;
cnt[2] += z;
for(size_t k = 0; k < verts.size(); k+=3)
{
verts[k+0] += x;
verts[k+1] += y;
verts[k+2] += z;
}
}
static void radix_sort_dist(std::vector<face2gl> & set) static void radix_sort_dist(std::vector<face2gl> & set)
{ {
static std::vector<face2gl> tmp; static std::vector<face2gl> tmp;
...@@ -1281,7 +1298,7 @@ public: ...@@ -1281,7 +1298,7 @@ public:
double px,py,z; double px,py,z;
file << "<g stroke=\"black\">" << std::endl; file << "<g stroke=\"black\">" << std::endl;
file << "<polyline fill=\"none\" points=\""; file << "<polyline fill=\"none\" points=\"";
for(unsigned k = 0; k < verts.size(); k+=3) for(unsigned k = 0; k < verts.size()+3; k+=3)
{ {
gluProject(verts[k%verts.size()+0],verts[k%verts.size()+1],verts[k%verts.size()+2],modelview,projection,viewport,&px,&py,&z); py = height-py; gluProject(verts[k%verts.size()+0],verts[k%verts.size()+1],verts[k%verts.size()+2],modelview,projection,viewport,&px,&py,&z); py = height-py;
file << px << "," << py << " "; file << px << "," << py << " ";
...@@ -3599,7 +3616,7 @@ void keyboard(unsigned char key, int x, int y) ...@@ -3599,7 +3616,7 @@ void keyboard(unsigned char key, int x, int y)
} }
else if( key == 'e' ) else if( key == 'e' )
{ {
drawedges = (drawedges+1)%4; drawedges = (drawedges+1)%(4+is_material_defined);
glutPostRedisplay(); glutPostRedisplay();
} }
else if( key == 'w' ) else if( key == 'w' )
...@@ -4252,7 +4269,24 @@ void draw_screen() ...@@ -4252,7 +4269,24 @@ void draw_screen()
//glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5); //glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5);
if( drawedges == 4 )
{
clip_boundary.clear();
for(std::map<int,std::vector<HandleType> >::iterator it = material_faces.begin(); it != material_faces.end(); ++it)
{
for(std::vector<HandleType>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt)
{
clip_boundary.push_back(DrawFace(Face(mesh,*jt)));
clip_boundary.back().shift(material_x[it->first],material_y[it->first],material_z[it->first]);
clip_boundary.back().set_color(0.6,0.6,0.6,1);
}
}
draw_faces(clip_boundary);
glColor4f(0,0,0,1);
draw_edges(clip_boundary);
clipboxupdate = true;
}
else
{ {
if( oclipper ) if( oclipper )
...@@ -4572,20 +4606,33 @@ void draw_screen() ...@@ -4572,20 +4606,33 @@ void draw_screen()
if( k < slen && l < slen && l+1 < slen ) if( k < slen && l < slen && l+1 < slen )
{ {
bool is_number = true;
for(int r = l+1; r < slen; ++r)
if( !isdigit(visualization_prompt[r]) )
is_number = false;
if( !is_number ) for(int r = l+1; r < slen; ++r) visualization_prompt[r] = tolower(visualization_prompt[r]);
strcpy(typen,visualization_prompt); strcpy(typen,visualization_prompt);
strcpy(name,visualization_prompt+k+1); strcpy(name,visualization_prompt+k+1);
if( is_number )
comp = atoi(visualization_prompt+l+1); comp = atoi(visualization_prompt+l+1);
else if( std::string(visualization_prompt+l+1) == "mag" )
comp = ENUMUNDEF;
else
{
std::cout << "unknown name for component, expected number or 'mag'" << std::endl;
comp = ENUMUNDEF-1;
}
visualization_prompt[k] = ':'; visualization_prompt[k] = ':';
visualization_prompt[l] = ':'; visualization_prompt[l] = ':';
printf("type %s name %s comp %d\n",typen,name,comp); printf("type %s name %s comp %d\n",typen,name,comp);
std::string stype(typen), sname(name); std::string stype(typen), sname(name);
if( mesh->HaveTag(sname) ) if( mesh->HaveTag(sname) && comp != ENUMUNDEF-1)
{ {
Tag source_tag = mesh->GetTag(sname); Tag source_tag = mesh->GetTag(sname);
if( source_tag.GetDataType() == DATA_REAL || source_tag.GetDataType() == DATA_INTEGER ) if( source_tag.GetDataType() == DATA_REAL || source_tag.GetDataType() == DATA_INTEGER )
{ {
if( comp >= 0 && comp < source_tag.GetSize() ) if( (comp >= 0 && comp < source_tag.GetSize()) || comp == ENUMUNDEF )
{ {
visualization_type = NONE; visualization_type = NONE;
for(size_t q = 0; q < stype.size(); ++q) for(size_t q = 0; q < stype.size(); ++q)
...@@ -4622,12 +4669,35 @@ void draw_screen() ...@@ -4622,12 +4669,35 @@ void draw_screen()
Storage::real_array coords = it->Coords(); Storage::real_array coords = it->Coords();
Storage::real cnt[3], dist, wgt; Storage::real cnt[3], dist, wgt;
Storage::real val = 0.0, vol = 0.0, res; Storage::real val = 0.0, vol = 0.0, res;
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && jt->GetDataSize(source_tag) > comp ) for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && (jt->GetDataSize(source_tag) > comp || comp == ENUMUNDEF) )
{ {
jt->Centroid(cnt); jt->Centroid(cnt);
dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]); dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]);
wgt = 1.0/(dist+1.0e-8); wgt = 1.0/(dist+1.0e-8);
val += wgt * (source_tag.GetDataType() == DATA_REAL ? jt->RealArray(source_tag)[comp] : static_cast<Storage::real>(jt->IntegerArray(source_tag)[comp]) ); if( source_tag.GetDataType() == DATA_REAL )
{
Storage::real_array v = jt->RealArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
else if( source_tag.GetDataType() == DATA_INTEGER )
{
Storage::integer_array v = jt->IntegerArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
vol += wgt; vol += wgt;
} }
res = val/vol; res = val/vol;
...@@ -4643,12 +4713,35 @@ void draw_screen() ...@@ -4643,12 +4713,35 @@ void draw_screen()
it->Centroid(coords); it->Centroid(coords);
Storage::real cnt[3], dist, wgt; Storage::real cnt[3], dist, wgt;
Storage::real val = 0.0, vol = 0.0, res; Storage::real val = 0.0, vol = 0.0, res;
for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && jt->GetDataSize(source_tag) > comp ) for(ElementArray<Element>::iterator jt = elems.begin(); jt != elems.end(); ++jt) if( jt->HaveData(source_tag) && (jt->GetDataSize(source_tag) > comp || comp == ENUMUNDEF) )
{ {
jt->Centroid(cnt); jt->Centroid(cnt);
dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]); dist = (cnt[0]-coords[0])*(cnt[0]-coords[0])+(cnt[1]-coords[1])*(cnt[1]-coords[1])+(cnt[2]-coords[2])*(cnt[2]-coords[2]);
wgt = 1.0/(dist+1.0e-8); wgt = 1.0/(dist+1.0e-8);
val += wgt * (source_tag.GetDataType() == DATA_REAL ? jt->RealArray(source_tag)[comp] : static_cast<Storage::real>(jt->IntegerArray(source_tag)[comp]) ); if( source_tag.GetDataType() == DATA_REAL )
{
Storage::real_array v = jt->RealArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
else if( source_tag.GetDataType() == DATA_INTEGER )
{
Storage::integer_array v = jt->IntegerArray(source_tag);
if( comp == ENUMUNDEF )
{
double l = 0;
for(unsigned q = 0; q < v.size(); ++q) l += v[q]*v[q];
l = sqrt(l);
val += wgt * l;
}
else val += wgt * v[comp];
}
vol += wgt; vol += wgt;
} }
res = val/vol; res = val/vol;
...@@ -4781,7 +4874,24 @@ void svg_draw(std::ostream & file) ...@@ -4781,7 +4874,24 @@ void svg_draw(std::ostream & file)
//glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5); //glTranslated((l+r)*0.5,(b+t)*0.5,(near+far)*0.5);
if( drawedges == 4 )
{
std::vector<face2gl> sorted_clip_boundary;
for(std::map<int,std::vector<HandleType> >::iterator it = material_faces.begin(); it != material_faces.end(); ++it)
{
for(std::vector<HandleType>::iterator jt = it->second.begin(); jt != it->second.end(); ++jt)
{
sorted_clip_boundary.push_back(DrawFace(Face(mesh,*jt)));
sorted_clip_boundary.back().shift(material_x[it->first],material_y[it->first],material_z[it->first]);
sorted_clip_boundary.back().compute_dist(campos);
sorted_clip_boundary.back().set_color(1,1,1,1);
}
}
face2gl::radix_sort_dist(sorted_clip_boundary);
//std::sort(sorted_clip_boundary.rbegin(),sorted_clip_boundary.rend());
svg_draw_faces(file,sorted_clip_boundary,modelview,projection,viewport);
}
else
{ {
if( oclipper ) if( oclipper )
...@@ -5185,6 +5295,58 @@ int main(int argc, char ** argv) ...@@ -5185,6 +5295,58 @@ int main(int argc, char ** argv)
} }
} }
if( mesh->HaveTag("MATERIAL") )
{
is_material_defined = 1;
Tag mat = mesh->GetTag("MATERIAL");
for(Mesh::iteratorFace it = mesh->BeginFace(); it != mesh->EndFace(); ++it)
{
int m1 = -1, m2 = -1;
if( it->BackCell().isValid() ) m1 = it->BackCell()->Integer(mat);
if( it->FrontCell().isValid() ) m2 = it->FrontCell()->Integer(mat);
if( m1 != m2 )
{
if( m1 >= 0 ) material_faces[m1].push_back(it->GetHandle());
if( m2 >= 0 ) material_faces[m2].push_back(it->GetHandle());
}
}
std::map<int,double> material_v;
double gx = 0, gy = 0, gz = 0, gv = 0;
for(Mesh::iteratorCell it = mesh->BeginCell(); it != mesh->EndCell(); ++it)
{
double cnt[3], v = it->Volume();
it->Centroid(cnt);
int m = it->Integer(mat);
material_x[m] += cnt[0]*v;
material_y[m] += cnt[1]*v;
material_z[m] += cnt[2]*v;
material_v[m] += v;
gx += cnt[0]*v;
gy += cnt[1]*v;
gz += cnt[2]*v;
gv += v;
}
gx /= gv;
gy /= gv;
gz /= gv;
for(std::map<int,double>::iterator it = material_v.begin(); it != material_v.end(); ++it)
{
double & x = material_x[it->first];
double & y = material_y[it->first];
double & z = material_z[it->first];
x /= it->second;
y /= it->second;
z /= it->second;
double dx = x - gx;
double dy = y - gy;
double dz = z - gz;
x = dx * 0.65;
y = dy * 0.65;
z = dz * 0.65;
}
}
quatinit(); quatinit();
glutInit(&argc,argv); glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
......
...@@ -468,11 +468,12 @@ namespace INMOST ...@@ -468,11 +468,12 @@ namespace INMOST
template<typename typeB> template<typename typeB>
Matrix & operator =(Matrix<typeB> const & other) Matrix & operator =(Matrix<typeB> const & other)
{ {
if( n*m != other.n*other.m ) space.resize(other.n*other.m); if( Cols()*Rows() != other.Cols()*other.Rows() ) space.resize(other.Cols()*other.Rows());
for(enumerator i = 0; i < other.n*other.m; ++i) for(enumerator i = 0; i < other.Rows(); ++i)
space[i] = get_value(other.space[i]); for(enumerator j = 0; j < other.Cols(); ++j)
n = other.n; assign((*this)(i,j),other(i,j));
m = other.m; n = other.Rows();
m = other.Cols();
return *this; return *this;
} }
// i is in [0,n] - row index // i is in [0,n] - row index
...@@ -737,6 +738,8 @@ namespace INMOST ...@@ -737,6 +738,8 @@ namespace INMOST
const Var * data() const {return space.data();} const Var * data() const {return space.data();}
enumerator Rows() const {return n;} enumerator Rows() const {return n;}
enumerator Cols() const {return m;} enumerator Cols() const {return m;}
enumerator & Rows() {return n;}
enumerator & Cols() {return m;}
void Print(INMOST_DATA_REAL_TYPE threshold = 1.0e-10) const void Print(INMOST_DATA_REAL_TYPE threshold = 1.0e-10) const
{ {
for(enumerator k = 0; k < n; ++k) for(enumerator k = 0; k < n; ++k)
...@@ -1105,6 +1108,13 @@ namespace INMOST ...@@ -1105,6 +1108,13 @@ namespace INMOST
} }
return ret; return ret;
} }
//change representation of the matrix into matrix of another size
void Repack(enumerator _n, enumerator _m)
{
assert(n*m==_n*_m);
n = _n;
m = _m;
}
}; };
typedef Matrix<INMOST_DATA_REAL_TYPE> rMatrix; //shortcut for real matrix typedef Matrix<INMOST_DATA_REAL_TYPE> rMatrix; //shortcut for real matrix
......
...@@ -1463,6 +1463,42 @@ namespace INMOST ...@@ -1463,6 +1463,42 @@ namespace INMOST
} }
}; };
template<class A, class B>
class atan2_expression : public shell_expression<atan2_expression<A,B> >
{
const A & left;
const B & right;
INMOST_DATA_REAL_TYPE value, ldmult, rdmult;
public:
atan2_expression(const shell_expression<A> & pleft, const shell_expression<B> & pright) : left(pleft), right(pright)
{
INMOST_DATA_REAL_TYPE lval = left.GetValue();
INMOST_DATA_REAL_TYPE rval = right.GetValue();
value = ::atan2(lval,rval);
ldmult = rval/(rval*rval+lval*lval);
rdmult = -lval/(rval*rval+lval*lval);
}
atan2_expression(const atan2_expression & other)
:left(other.left), right(other.right), value(other.value),
ldmult(other.ldmult), rdmult(other.rdmult) {}
__INLINE INMOST_DATA_REAL_TYPE GetValue() const { return value; }
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::RowMerger & r) const
{
left.GetJacobian(mult*ldmult,r);
right.GetJacobian(mult*rdmult,r);
}
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::Row & r) const
{
left.GetJacobian(mult*ldmult,r);
right.GetJacobian(mult*rdmult,r);
}
__INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const
{
throw NotImplemented;
}
};
template<class A> template<class A>
class pow_const_expression : public shell_expression<pow_const_expression<A> > class pow_const_expression : public shell_expression<pow_const_expression<A> >
{ {
...@@ -1824,18 +1860,25 @@ template<class A> __INLINE INMOST_DATA_REAL_TY ...@@ -1824,18 +1860,25 @@ template<class A> __INLINE INMOST_DATA_REAL_TY
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg.SetValue(Val.GetValue()); } __INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg.SetValue(Val.GetValue()); } __INLINE void set_value(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg.SetValue(Val.GetValue()); }
__INLINE void assign(INMOST::var_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;} __INLINE void assign(INMOST::var_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST::multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;} __INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val;}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::var_expression & Val) {Arg = Val.GetValue();} __INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::var_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression & Val) {Arg = Val.GetValue();} __INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val.GetValue();} __INLINE void assign(INMOST_DATA_REAL_TYPE & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val.GetValue();}
__INLINE void assign(INMOST::multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::var_expression & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::var_expression & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; } __INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::multivar_expression_reference & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, INMOST_DATA_REAL_TYPE Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::var_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::multivar_expression & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::multivar_expression_reference & Val) {Arg = Val; }
__INLINE void assign(INMOST::hessian_multivar_expression & Arg, const INMOST::hessian_multivar_expression & Val) {Arg = Val; }
template<class A> __INLINE INMOST::soft_abs_expression<A> soft_fabs(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_abs_expression<A>(Arg,tol); } template<class A> __INLINE INMOST::soft_abs_expression<A> soft_fabs(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_abs_expression<A>(Arg,tol); }
__INLINE INMOST_DATA_REAL_TYPE soft_fabs(INMOST_DATA_REAL_TYPE Arg, INMOST_DATA_REAL_TYPE tol) {return ::sqrt(Arg*Arg+tol*tol);} __INLINE INMOST_DATA_REAL_TYPE soft_fabs(INMOST_DATA_REAL_TYPE Arg, INMOST_DATA_REAL_TYPE tol) {return ::sqrt(Arg*Arg+tol*tol);}
template<class A> __INLINE INMOST::soft_sign_expression<A> soft_sign(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_sign_expression<A>(Arg,tol); } template<class A> __INLINE INMOST::soft_sign_expression<A> soft_sign(INMOST::shell_expression<A> const & Arg, INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_sign_expression<A>(Arg,tol); }
...@@ -1845,6 +1888,7 @@ template<class A, class B> __INLINE INMOST::division_expression<A, ...@@ -1845,6 +1888,7 @@ template<class A, class B> __INLINE INMOST::division_expression<A,
template<class A, class B> __INLINE INMOST::addition_expression<A, B> operator+(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::addition_expression<A, B> (Left, Right); } template<class A, class B> __INLINE INMOST::addition_expression<A, B> operator+(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::addition_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::subtraction_expression<A, B> operator-(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::subtraction_expression<A, B> (Left, Right); } template<class A, class B> __INLINE INMOST::subtraction_expression<A, B> operator-(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::subtraction_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::pow_expression<A, B> pow(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::pow_expression<A, B> (Left, Right); } template<class A, class B> __INLINE INMOST::pow_expression<A, B> pow(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::pow_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::atan2_expression<A, B> atan2(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right) { return INMOST::atan2_expression<A, B> (Left, Right); }
template<class A, class B> __INLINE INMOST::soft_max_expression<A, B> soft_max(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_max_expression<A, B> (Left, Right,tol); } template<class A, class B> __INLINE INMOST::soft_max_expression<A, B> soft_max(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_max_expression<A, B> (Left, Right,tol); }
__INLINE INMOST_DATA_REAL_TYPE soft_max(INMOST_DATA_REAL_TYPE Left, INMOST_DATA_REAL_TYPE Right, INMOST_DATA_REAL_TYPE tol) {return 0.5*(Left+Right+::sqrt((Left-Right)*(Left-Right)+tol*tol));} __INLINE INMOST_DATA_REAL_TYPE soft_max(INMOST_DATA_REAL_TYPE Left, INMOST_DATA_REAL_TYPE Right, INMOST_DATA_REAL_TYPE tol) {return 0.5*(Left+Right+::sqrt((Left-Right)*(Left-Right)+tol*tol));}
template<class A, class B> __INLINE INMOST::soft_min_expression<A, B> soft_min(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_min_expression<A, B> (Left, Right,tol); } template<class A, class B> __INLINE INMOST::soft_min_expression<A, B> soft_min(INMOST::shell_expression<A> const & Left, INMOST::shell_expression<B> const & Right ,INMOST_DATA_REAL_TYPE tol) { return INMOST::soft_min_expression<A, B> (Left, Right,tol); }
......
...@@ -1184,6 +1184,8 @@ namespace INMOST ...@@ -1184,6 +1184,8 @@ namespace INMOST
} }
else fout << " "; else fout << " ";
} }
else if( !t->isSparse(etype) ) fout << " { } ";
} }
break; break;
case DATA_INTEGER: case DATA_INTEGER:
...@@ -1215,6 +1217,7 @@ namespace INMOST ...@@ -1215,6 +1217,7 @@ namespace INMOST
else fout << " "; else fout << " ";
//fout << std::endl; //fout << std::endl;
} }
else if( !t->isSparse(etype) ) fout << " { } ";
} }
break; break;
case DATA_BULK: case DATA_BULK:
...@@ -1246,6 +1249,7 @@ namespace INMOST ...@@ -1246,6 +1249,7 @@ namespace INMOST
else fout << " "; else fout << " ";
//fout << std::endl; //fout << std::endl;
} }
else if( !t->isSparse(etype) ) fout << " { } ";
} }
break; break;
case DATA_REFERENCE: case DATA_REFERENCE:
...@@ -1291,6 +1295,7 @@ namespace INMOST ...@@ -1291,6 +1295,7 @@ namespace INMOST
else fout << " "; else fout << " ";
//fout << std::endl; //fout << std::endl;
} }
else if( !t->isSparse(etype) ) fout << " { } ";
} }
break; break;
case DATA_REMOTE_REFERENCE: case DATA_REMOTE_REFERENCE:
...@@ -1336,6 +1341,7 @@ namespace INMOST ...@@ -1336,6 +1341,7 @@ namespace INMOST
else fout << " "; else fout << " ";
//fout << std::endl; //fout << std::endl;
} }
else if( !t->isSparse(etype) ) fout << " { } ";
} }
break;