//===========================================================================
// GoTools - SINTEF Geometry Tools version 1.0
//
// GoTools module: Implicitization, version 0.9
//
// Copyright (C) 2000-2005 SINTEF ICT, Applied Mathematics, Norway.
//
// This program is free software; you can redistribute it and/or          
// modify it under the terms of the GNU General Public License            
// as published by the Free Software Foundation version 2 of the License. 
//
// This program is distributed in the hope that it will be useful,        
// but WITHOUT ANY WARRANTY; without even the implied warranty of         
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
// GNU General Public License for more details.                           
//
// You should have received a copy of the GNU General Public License      
// along with this program; if not, write to the Free Software            
// Foundation, Inc.,                                                      
// 59 Temple Place - Suite 330,                                           
// Boston, MA  02111-1307, USA.                                           
//
// Contact information: e-mail: tor.dokken@sintef.no                      
// SINTEF ICT, Department of Applied Mathematics,                         
// P.O. Box 124 Blindern,                                                 
// 0314 Oslo, Norway.                                                     
//
// Other licenses are also available for this software, notably licenses
// for:
// - Building commercial software.                                        
// - Building software whose source code you wish to keep private.        
//===========================================================================
#include "BernsteinTriangularPoly.h"
#include <vector>
#include <fstream>


using namespace Go;
using namespace std;


int main()
{
    cout << "*** BernsteinTriangularPoly ***" << endl;
    cout << endl;

    // Construct from vector<double>
    double arr[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
    int num = sizeof(arr)/sizeof(double);
    vector<double> coefs(arr, arr+num);
    BernsteinTriangularPoly b(2, coefs);

    cout << "*** Access functions ***" << endl;
    // degree()
    int deg = b.degree();
    cout << deg << endl;
    // operator[]
    double co = b[4];
    cout << co << endl;
    const BernsteinTriangularPoly c = b;
    double cco = c[3];
    cout << cco << endl;
    cout << endl;

    // operator()
    cout << "*** operator() ***" << endl;
    // Construct a linear polynomial
    int deg1 = 1;
    double c1[] = { 0.0, 1.0, 1.0 };
    BernsteinTriangularPoly p1(deg1, c1, c1+3);
    cout << "p1:\n" << p1 << endl;
    Vector3D u(0.3333, 0.3333, 0.3333);
    cout << u << endl << p1(u) << endl;
    cout << endl;

    // norm() and normalize()
    cout << "*** norm() and normalize() ***" << endl;
    BernsteinTriangularPoly h = b;
    cout << "h:\n" << h << endl
	 << "h.norm() = " << h.norm() << endl;
    h.normalize();
    cout << "h:\n" << h << endl
	 << "h.norm() = " << h.norm() << endl;
    cout << endl;

     // deriv()
    cout << "*** deriv() ***" << endl;
    Vector3D d(-1.0, 0.5, 0.5);
    BernsteinTriangularPoly p1der;
    p1.deriv(1, d, p1der);
    cout << "p1':\n" << p1der << endl;
    cout << endl;

    // blossom()
    cout << "*** blossom() ***" << endl;
    int degh = h.degree();
    Vector3D e1(1.0, 0.0, 0.0);
    Vector3D e2(0.0, 1.0, 0.0);
    Vector3D e3(0.0, 0.0, 1.0);
    for (int i = degh; i >= 0; --i) {
	for (int j = degh - i; j >= 0; --j) {
	    int k = degh - i - j;
	    vector<Vector3D> uvec(i, e1);
	    vector<Vector3D> v2(j, e2);
	    uvec.insert(uvec.end(), v2.begin(), v2.end());
	    vector<Vector3D> v3(k, e3);
	    uvec.insert(uvec.end(), v3.begin(), v3.end());
	    cout << h.blossom(uvec) << endl;
	}
    }
    Vector3D mid(0.3333, 0.3333, 0.3333);
    vector<Vector3D> uvec(p1.degree(), mid);
    double x = p1.blossom(uvec);
    cout << "p1(0.3333, 0.3333, 0.3333, 0.3333) = " << x << endl;
    cout << endl;

    // read() and write()
    cout << "*** read() and write() ***" << endl;
    ifstream in("data/bernstein_triangular_poly.dat");
    BernsteinTriangularPoly f;
    in >> f;
    cout << f << endl;
    cout << endl;

    return 0;
}
