예제 #1
0
/**
 * Is the face front for the eye point
 * @param face
 * @return 
 */
bool ConvexHull::isFront(int f, int eye) {
    int kv[4];
    getVerticesOfTriangle(f, kv);
    kv[3] = eye;
    Vector3d va[] = { hva[kv[0]], hva[kv[1]], hva[kv[2]], hva[kv[3]] };
    return determ(kv, va);
}
예제 #2
0
/**
 * Is the face front
 * @param face
 * @return 
 */
bool ConvexHull::isFront(int f) {
    int kv[4];
    getVerticesOfTriangle(f, kv);
    kv[3] = hva.size();
    Vector3d va[] = { Vector3d(hva[kv[0]].x(), hva[kv[0]].y(), 0.0),
                      Vector3d(hva[kv[1]].x(), hva[kv[1]].y(), 0.0),
                      Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), 0.0),
                      Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), SCALE) };
    return determ(kv, va);
}
예제 #3
0
/**
 * Wraps 2 convex hulls in cylindrical
 * @param common tangent edge
 */
void ConvexHull::wrapInCylindrical(int cte0) {
    int cte1 = cte0;
    int cte2 = cte0;
    int liv0 = ksv[cte0];
    int riv0 = kev[cte0];
    int liv1 = liv0;
    int riv1 = riv0;
    do {
        cte1 = cte2;
        
        // searches the edge of the common tangent face
        int le = searchEdgeOfCTFace(liv1, riv1, ScanDir::CW);
        int re = searchEdgeOfCTFace(riv1, liv1, ScanDir::CCW);
        int liv2 = (liv1 == ksv[le] ? kev[le] : ksv[le]);
        int riv2 = (riv1 == ksv[re] ? kev[re] : ksv[re]);
        
        // searches the exterior edge of the common tangent face
        int kv[] = { riv1, liv1, riv2, liv2 };
        Vector3d va[] = { hva[kv[0]], hva[kv[1]], hva[kv[2]], hva[kv[3]] };
        bool lext = determ(kv, va);
        if (lext) {
            kep[le] = PrimProperty::BOUNDARY;
            liv1 = liv2;
        } else {
            kep[re] = PrimProperty::BOUNDARY;
            riv1 = riv2;
        }
        // entries new common tangent face
        int f = newFace();
        kfp[f] = PrimProperty::NEW;
        if (liv1 == liv0 && riv1 == riv0) {
            cte2 = cte0;
        } else {
            cte2 = newEdge();
            kep[cte2] = PrimProperty::NEW;
        }
        klf[cte2] = f;
        krf[cte1] = f;
        kfe[f]    = cte2;
        ksv[cte2] = liv1;
        kev[cte2] = riv1;
        if (lext) {
            kscce[cte2] = le;
            ksce[cte1]  = le;
            kece[cte2]  = cte1;
            kecce[cte1] = cte2;
        } else {
            kece[cte2]  = re;
            kecce[cte1] = re;
            kscce[cte2] = cte1;
            ksce[cte1]  = cte2;
        }
    } while (cte2 != cte0);
}
예제 #4
0
/**
 * Is left the direction of 4 vertices
 * @param id of vertices
 * @param vertices
 * @return left or not
 */
bool ConvexHull::determ(const int* kv0, const Vector3d* va0) {
    int* kv = new int[4];
    Vector3d* va = new Vector3d[4];
    copy(kv0, kv0 + 4, kv);
    copy(va0, va0 + 4, va);
    // sorts vertices by id
    bool even = sortById(kv, va);
    // calculates determinant
    bool posi = determ(va);
    Memory::releaseArray(&kv);
    Memory::releaseArray(&va);
    return !(even ^ posi);
}
예제 #5
0
/**
 * Searches the common tangent edge
 * @param vertex of left convex hull
 * @param cyclic list of vertices on the silhouette of the left convex hull
 * @param vertex of right convex hull
 * @param cyclic list of vertices on the silhouette of the right convex hull
 * @param turnning direction
 */
void ConvexHull::searchCTEdge(int& liv, unordered_map<int, int>& klnxv, int& riv, unordered_map<int, int>& krnxv, bool dir) {
    bool changed = false;
    do {
        changed = false;
        // searches the vertex of the common tangent edge on the right convex hull
        while (1) {
            int nxv = krnxv[riv];
            int kv[] = { liv, riv, nxv, (int)hva.size() };
            Vector3d va[] = { Vector3d(hva[kv[0]].x(), hva[kv[0]].y(), 0.0),
                              Vector3d(hva[kv[1]].x(), hva[kv[1]].y(), 0.0),
                              Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), 0.0),
                              Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), SCALE) };
            if (determ(kv, va) == dir) {
                break;
            }
            krnxv.erase(riv);
            riv = nxv;
            changed = true;
        }
        // searches the vertex of the common tangent edge on the left convex hull
        while (1) {
            int nxv = klnxv[liv];
            int kv[] = { riv, liv, nxv, (int)hva.size() };
            Vector3d va[] = { Vector3d(hva[kv[0]].x(), hva[kv[0]].y(), 0.0),
                              Vector3d(hva[kv[1]].x(), hva[kv[1]].y(), 0.0),
                              Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), 0.0),
                              Vector3d(hva[kv[2]].x(), hva[kv[2]].y(), SCALE) };
            if (determ(kv, va) != dir) {
                break;
            }
            klnxv.erase(liv);
            liv = nxv;
            changed = true;
        }
    } while (changed);
}
예제 #6
0
/**
 * Calculates determinant
 * @param vertices
 * @return positive or not of determinant
 */
bool ConvexHull::determ(const Vector3d* va) {
    Vector3d dij = va[1] - va[0];
    Vector3d dik = va[2] - va[0];
    Vector3d dil = va[3] - va[0];
    Vector3d djk = va[2] - va[1];
    Vector3d djl = va[3] - va[1];
    Vector3d dkl = va[3] - va[2];

    // Calculates in floating point number
    int is = 0;
    double df[][3] = {{dij.x(), dij.y(), dij.z()},
                      {dik.x(), dik.y(), dik.z()},
                      {dil.x(), dil.y(), dil.z()}};
    if ((is = determ(df)) != 0)    { return (is > 0 ? true : false); }

    // Calculates in integer and symbol perturbation
    INT128 d0[][3] = {{ (INT128)dij.x(), (INT128)dij.y(), (INT128)dij.z() },
                      { (INT128)dik.x(), (INT128)dik.y(), (INT128)dik.z() },
                      { (INT128)dil.x(), (INT128)dil.y(), (INT128)dil.z() }};
    if ((is = determ(d0)) != 0)    { return (is > 0 ? true : false); }
    
    INT128 d1[][2] = {{ (INT128)djk.y(), (INT128)djk.z() },
                      { (INT128)djl.y(), (INT128)djl.z() }};
    if ((is = -determ(d1)) != 0)   { return (is > 0 ? true : false); }
    
    INT128 d2[][2] = {{ (INT128)dik.y(), (INT128)dik.z() },
                      { (INT128)dil.y(), (INT128)dil.z() }};
    if ((is = determ(d2)) != 0)    { return (is > 0 ? true : false); }
    
    INT128 d3[][2] = {{ (INT128)dij.y(), (INT128)dij.z() },
                      { (INT128)dil.y(), (INT128)dil.z() }};
    if ((is = -determ(d3)) != 0)   { return (is > 0 ? true : false); }
    
    INT128 d4[][2] = {{ (INT128)djk.x(), (INT128)djk.z() },
                      { (INT128)djl.x(), (INT128)djl.z() }};
    if ((is = determ(d4)) != 0)    { return (is > 0 ? true : false); }

    if ((is = -(int)dkl.z()) != 0) { return (is > 0 ? true : false); }

    if ((is = (int)djl.z()) != 0)  { return (is > 0 ? true : false); }
    
    INT128 d7[][2] = {{ (INT128)dik.x(), (INT128)dik.z() },
                      { (INT128)dil.x(), (INT128)dil.z() }};
    if ((is = -determ(d7)) != 0)   { return (is > 0 ? true : false); }

    if ((is = -(int)dil.z()) != 0) { return (is > 0 ? true : false); }
    
    INT128 d9[][2] = {{ (INT128)dij.x(), (INT128)dij.z() },
                      { (INT128)dil.x(), (INT128)dil.z() }};
    if ((is = determ(d9)) != 0)    { return (is > 0 ? true : false); }
    
    INT128 d10[][2] = {{ (INT128)djk.x(), (INT128)djk.y() },
                       { (INT128)djl.x(), (INT128)djl.y() }};
    if ((is = -determ(d10)) != 0)  { return (is > 0 ? true : false); }

    if ((is = (int)dkl.y()) != 0)  { return (is > 0 ? true : false); }

    if ((is = -(int)djl.y()) != 0) { return (is > 0 ? true : false); }

    if ((is = -(int)dkl.x()) != 0) { return (is > 0 ? true : false); }
    
    return true;
}
예제 #7
0
/**
 * Constructs the tetrahedron
 * @param vertex of the tetrahedron
 */
void ConvexHull::constTetrahedron(int iv) {
    int kv[] = { iv, iv+1, iv+2, iv+3 };
    Vector3d va[] = { hva[kv[0]], hva[kv[1]], hva[kv[2]], hva[kv[3]] };
    if (determ(kv, va)) {
        kv[2] = iv + 3;
        kv[3] = iv + 2;
    }
    
    // entries cyclic list of vertices
    for (int i = 0; i < NTV; i++) {
        int nxv = kv[(i+1)%NTV];
        khnv[kv[i]] = nxv;
        khpv[nxv]  = kv[i];
    }
    
    // gets index of new edges and faces
    int ke[] = { newEdge(), newEdge(), newEdge(), newEdge(), newEdge(), newEdge() };
    int kf[] = { newFace(), newFace(), newFace(), newFace() };
    
    // connects faces to edges
    kfe[kf[0]] = ke[0];
    kfe[kf[1]] = ke[1];
    kfe[kf[2]] = ke[2];
    kfe[kf[3]] = ke[3];
    
    // connects vertices to edges
    kve[kv[0]] = ke[0];
    kve[kv[1]] = ke[0];
    kve[kv[2]] = ke[4];
    kve[kv[3]] = ke[4];
    
    // connects edges to start and end vertices
    ksv[ke[0]] = kv[1];
    ksv[ke[1]] = kv[2];
    ksv[ke[2]] = kv[3];
    ksv[ke[3]] = kv[1];
    ksv[ke[4]] = kv[2];
    ksv[ke[5]] = kv[3];
    kev[ke[0]] = kv[0];
    kev[ke[1]] = kv[0];
    kev[ke[2]] = kv[0];
    kev[ke[3]] = kv[2];
    kev[ke[4]] = kv[3];
    kev[ke[5]] = kv[1];
    
    // connects edges to left and right faces
    klf[ke[0]] = kf[2];
    klf[ke[1]] = kf[0];
    klf[ke[2]] = kf[1];
    klf[ke[3]] = kf[0];
    klf[ke[4]] = kf[1];
    klf[ke[5]] = kf[2];
    krf[ke[0]] = kf[0];
    krf[ke[1]] = kf[1];
    krf[ke[2]] = kf[2];
    krf[ke[3]] = kf[3];
    krf[ke[4]] = kf[3];
    krf[ke[5]] = kf[3];

    // connects edges to contiguous edges
    ksce[ke[0]]  = ke[3];
    ksce[ke[1]]  = ke[4];
    ksce[ke[2]]  = ke[5];
    ksce[ke[3]]  = ke[5];
    ksce[ke[4]]  = ke[3];
    ksce[ke[5]]  = ke[4];
    kscce[ke[0]] = ke[5];
    kscce[ke[1]] = ke[3];
    kscce[ke[2]] = ke[4];
    kscce[ke[3]] = ke[0];
    kscce[ke[4]] = ke[1];
    kscce[ke[5]] = ke[2];
    kece[ke[0]]  = ke[2];
    kece[ke[1]]  = ke[0];
    kece[ke[2]]  = ke[1];
    kece[ke[3]]  = ke[1];
    kece[ke[4]]  = ke[2];
    kece[ke[5]]  = ke[0];
    kecce[ke[0]] = ke[1];
    kecce[ke[1]] = ke[2];
    kecce[ke[2]] = ke[0];
    kecce[ke[3]] = ke[4];
    kecce[ke[4]] = ke[5];
    kecce[ke[5]] = ke[3];
    
    // entries cyclic list of vertices on the silhouette of the convex hull
    // entries a left most vertex
    kch.push_back(searchSilhouette(NTV, kv));
}
예제 #8
0
quest13::Print(TList* plist, class test &t)
{
        int i, j, k;
        int a[3], b[3], c[3];
        int plane[4], vert[4][10], vert_t[4][10];
        int n, Right_Numb;

        char* buf = new char[256];
        char* buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        Right_Numb = random( 5 ) + 1;

        srand( keygen );

        for( i = 0; i < 3; i ++ )
        {
                a[i] = rgen( keygen, 1, amin, amax );

                b[i] = rgen( keygen, 1, amin, amax );
                while ( b[i] == a[i] )
                        b[i] = rgen( keygen, 1, amin, amax );

                c[i] = rgen( keygen, 1, amin, amax );
                while ( c[i] == b[i] || c[i] == a[i] )
                        c[i] = rgen( keygen, 1, amin, amax );

        }

        sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Найти общее уравнение плоскости зная 3 точки.)" );
        plist->Add( strdup(buf) );

        sprintf( buf, "A!(%d", a[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", a[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "B!(%d", b[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", b[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "C!(%d", c[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", c[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        for ( i = 0; i < 3; i ++ )
        {
                vert[0][i] = b[i];
                vert[1][i] = a[i] - b[i];
                vert[2][i] = c[i] - b[i];
        }

        for ( i = 0; i < 3; i ++ )
        {
                k = 0;

                for ( j = 0; j < 3; j ++ )
                {
                        if ( j != i )
                        {
                                vert_t[0][k] = vert[1][j];
                                vert_t[1][k] = vert[2][j];
                                k ++;
                        }
                }

                plane[i] = pow(-1,i) * determ( 2, vert_t );
        }

        plane[3] = - determ ( 3, vert );

        for( n = 0; n < 5; n ++ )
        {
                sprintf( buf, "String(\"Вариант %c):\")", 'a' + n );
                plist->Add( strdup(buf) );

                strcpy ( buf, "" );

                if ( plane[0] - ( Right_Numb - 1 ) + n )
                {
                        if ( plane[0] - ( Right_Numb - 1 ) + n == 1 )
                                sprintf( buf1, "x" );
                        else
                        if ( plane[0] - ( Right_Numb - 1 ) + n == -1 )
                                sprintf( buf1, "-x" );
                        else
                                sprintf( buf1, "%d*x", plane[0] - ( Right_Numb - 1 ) + n );

                        strcat ( buf, buf1 );
                }

                if ( plane[1] - ( Right_Numb - 1 ) + n )
                {
                        if ( plane[1] - ( Right_Numb - 1 ) + n == 1 )
                                sprintf( buf1, "+y" );
                        else
                        if ( plane[1] - ( Right_Numb - 1 ) + n == -1 )
                                sprintf( buf1, "-y" );
                        else
                                sprintf( buf1, "%+d*y", plane[1] - ( Right_Numb - 1 ) + n );

                        strcat ( buf, buf1 );
                }

                if ( plane[2] - ( Right_Numb - 1 ) + n )
                {
                        if ( plane[2] - ( Right_Numb - 1 ) + n == 1 )
                                sprintf( buf1, "+z" );
                        else
                        if ( plane[2] - ( Right_Numb - 1 ) + n == -1 )
                                sprintf( buf1, "-z" );
                        else
                                sprintf( buf1, "%+d*z", plane[2] - ( Right_Numb - 1 ) + n );

                        strcat ( buf, buf1 );
                }

                if ( plane[3] - ( Right_Numb - 1 ) + n )
                {
                        sprintf( buf1, "%+d", plane[3] - ( Right_Numb - 1 ) + n );
                        strcat( buf, buf1 );
                }

                if ( plane[0] || plane[1] || plane[2] || plane[3] )
                {
                        strcat( buf, "=0" );
                        plist->Add( strdup(buf) );
                }
        }

        /*sprintf(buf,"String(@Часть преподавателя )");
        plist->Add(strdup(buf));

        sprintf(buf,"String(\"Тема - %s \")",selecttask->name);
        plist->Add(strdup(buf));

        sprintf(buf,"String(ВАРИАНТ   %i, решение задачи %i, ключ %i)", nvar, nzad, keygen );
        plist->Add(strdup(buf));

        sprintf(buf,"String( Правильный ответ - %c)", 'a' + Right_Numb - 1 );
        plist->Add(strdup(buf));*/

        t.pr_tst = 1;
        t.ch_ask = 5;
        t.right_ask = Right_Numb;
        t.msg = "Тест успешно сгенерирован.";

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}
예제 #9
0
quest13::Print(TList* plist)
{
        int i, j, k;
        int a[3], b[3], c[3];
        int plane[4], vert[4][10], vert_t[4][10];

        char* buf = new char[256];
        char* buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        srand( keygen );

        for( i = 0; i < 3; i ++ )
        {
                a[i] = rgen( keygen, 1, amin, amax );

                b[i] = rgen( keygen, 1, amin, amax );
                while ( b[i] == a[i] )
                        b[i] = rgen( keygen, 1, amin, amax );

                c[i] = rgen( keygen, 1, amin, amax );
                while ( c[i] == b[i] || c[i] == a[i] )
                        c[i] = rgen( keygen, 1, amin, amax );

        }

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
                plist->Add( strdup(buf) );
        }
        else
        {
                sprintf( buf, "String(#)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(Найти общее уравнение плоскости зная 3 точки.)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "A!(%d", a[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", a[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "B!(%d", b[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", b[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "C!(%d", c[0] );

        for ( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", c[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(@Часть преподавателя )" );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(\"Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(ВАРИАНТ   %i, решение задачи %i, ключ %i)", nvar, nzad, keygen );
        plist->Add( strdup(buf) );

        for ( i = 0; i < 3; i ++ )
        {
                vert[0][i] = b[i];
                vert[1][i] = a[i] - b[i];
                vert[2][i] = c[i] - b[i];
        }

        for ( i = 0; i < 3; i ++ )
        {
                k = 0;

                for ( j = 0; j < 3; j ++ )
                {
                        if ( j != i )
                        {
                                vert_t[0][k] = vert[1][j];
                                vert_t[1][k] = vert[2][j];
                                k ++;
                        }
                }

                plane[i] = pow(-1,i) * determ( 2, vert_t );
        }

        plane[3] = - determ ( 3, vert );

        sprintf( buf, "String(Искомая плоскость: )" );
        plist->Add( strdup(buf) );

        sprintf( buf, "|Matrix(3,3" );

        for ( i = 0; i < 3; i ++ )
        for ( j = 0; j < 3; j ++ )
        {
                switch ( i )
                {
                        case 0:

                        sprintf( buf1, ",%d", a[j] - b[j] );

                        break;

                        case 1:

                        sprintf( buf1, ",%d", c[j] - b[j] );

                        break;

                        case 2:

                        if ( j == 0 )
                        if ( b[j] )
                                sprintf( buf1, ",x%+d", - b[j] );
                        else
                                sprintf( buf1, ",x" );
                        else
                        if ( j == 1 )
                        if ( b[j] )
                                sprintf( buf1, ",y%+d", - b[j] );
                        else
                                sprintf( buf1, ",y" );
                        else
                        if ( b[j] )
                                sprintf( buf1, ",z%+d", - b[j] );
                        else
                                sprintf( buf1, ",z" );
                }

                strcat( buf, buf1 );
        }

        strcat( buf, ")|=0" );
        plist->Add( strdup(buf) );

        strcpy ( buf, "" );

        if ( plane[0] )
        {
                if ( plane[0] == 1 )
                        sprintf( buf1, "x" );
                else
                if ( plane[0] == -1 )
                        sprintf( buf1, "-x" );
                else
                        sprintf( buf1, "%d*x", plane[0] );

                strcat ( buf, buf1 );
        }

        if ( plane[1] )
        {
                if ( plane[1] == 1 )
                        sprintf( buf1, "+y" );
                else
                if ( plane[1] == -1 )
                        sprintf( buf1, "-y" );
                else
                        sprintf( buf1, "%+d*y", plane[1] );

                strcat ( buf, buf1 );
        }

        if ( plane[2] )
        {
                if ( plane[2] == 1 )
                        sprintf( buf1, "+z" );
                else
                if ( plane[2] == -1 )
                        sprintf( buf1, "-z" );
                else
                        sprintf( buf1, "%+d*z", plane[2] );

                strcat ( buf, buf1 );
        }

        if ( plane[3] )
        {
                sprintf( buf1, "%+d", plane[3] );
                strcat( buf, buf1 );
        }

        if ( plane [0] || plane[1] || plane[2] || plane[3] )
        {
                strcat( buf, "=0" );
                plist->Add( strdup(buf) );
        }

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}
예제 #10
0
quest18::Print(TList* plist)
{
        int i, j, k;
        int p[4], a[3], b[3], c[3];
        int M[3], matr[2][2];

        double absc, absa;

        drobi d;

        char * buf = new char[256];
        char * buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        srand( keygen );

        for( i = 0; i < 4; i ++ )
        {
                a[i] = rgen( keygen, 1, amin, amax );
                M[i] = rgen( keygen, 1, amin, amax );
                p[i] = rgen( keygen, 1, amin, amax );

                while ( p[i] == M[i] )
                        p[i] = rgen( keygen, 1, amin, amax );
        }

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
                plist->Add( strdup(buf) );
        }
        else
        {
                sprintf( buf, "String(#)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(Найти расстояние от точки до прямой.)" );
                plist->Add( strdup(buf) );

                sprintf( buf, "String(Прямая задана уравнением:)" );
                plist->Add( strdup(buf) );
        }

        if( M[0] )
                sprintf( buf, "(x%+d)/%d=", -M[0], a[0] );
        else
                sprintf( buf, "x/%d=", a[0] );

        if( M[1] )
                sprintf( buf1, "(y%+d)/%d=", -M[1], a[1] );
        else
                sprintf( buf1, "y/%d=", a[1] );
        strcat( buf, buf1 );

        if( M[2] )
                sprintf( buf1, "(z%+d)/%d", -M[2], a[2] );
        else
                sprintf( buf1, "z/%d", a[2] );

        strcat( buf, buf1 );
        plist->Add( strdup(buf) );

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(Координаты точки:)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "A!(%d", p[0] );
        for( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", p[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "d=..." );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(@Часть преподавателя )" );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(\"Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(ВАРИАНТ   %i, решение задачи %i, ключ %i)", nvar, nzad, keygen );
        plist->Add( strdup(buf) );

        for ( i = 0; i < 3; i++ )
                b[i] = M[i] - p[i];

        for (i = 0; i < 3; i ++)
        {
                k = 0;

                for ( j = 0; j < 3; j ++ )
                {
                        if ( j != i )
                        {
                                matr[0][k] = a[j];
                                matr[1][k] = b[j];
                                k ++;
                        }
                }

                c[i] = pow ( -1, i ) * determ( 2, matr );
        }

        absc = 0;

        for ( i = 0; i < 3; i ++ )
                absc += c[i] * c[i];

        absa = 0;

        for ( i = 0; i < 3; i ++ )
                absa += a[i] * a[i];

        if ( !absc )
                sprintf( buf, "d=0" );
        else
        if ( ( ceil( sqrt( absc ) ) ) == ( sqrt( absc ) ) && ( ceil( sqrt( absa ) ) ) == ( sqrt( absa ) ) )
        {
                d = drobi( sqrt( absc ), sqrt( absa ) );
                //sprintf( buf, "d=%d/%d", d.a, d.b );
                sprintf( buf, "d=%s", DrobiToStr( d ) );
        }
        else
        if ( ( ceil( sqrt( absc ) ) ) == ( sqrt( absc ) ) )
                sprintf( buf, "d=%f/sqrt(%f)", sqrt( absc ), absa );
        else
        if ( ( ceil( sqrt( absa ) ) ) == ( sqrt( absa ) ) )
                sprintf( buf, "d=sqrt(%f)/%f", absc, sqrt( absa ) );
        else
                sprintf( buf, "d=sqrt(%f)/sqrt(%f)", absc, absa );

        plist->Add( strdup(buf) );

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}
예제 #11
0
파일: VISU.C 프로젝트: AoJ/SecondReality
int	calc_invrmatrix(rmatrix *r)
{
	double	m0[9];
	double	m[9];
	double	d[9];
	double	det;
	int	a,x,y;
	for(a=0;a<9;a++) m[a]=m0[a]=((double)r->m[a])/UNIT;
	d[0]= determ(1,2,1,2);
	d[1]=-determ(0,2,1,2);
	d[2]= determ(0,1,1,2);
	d[3]=-determ(1,2,0,2);
	d[4]= determ(0,2,0,2);
	d[5]=-determ(0,1,0,2);
	d[6]= determ(1,2,0,1);
	d[7]=-determ(0,2,0,1);
	d[8]= determ(0,1,0,1);
	det=m[0]*d[0]+m[1]*d[1]+m[2]*d[2];
	if(det>-0.0001 && det<0.0001) return(0); // could not invert
	for(x=0;x<3;x++) for(y=0;y<3;y++)
	{
		m[y+x*3]=d[x+y*3]/det;
	}
	for(a=0;a<9;a++) 
	{
		r->m[a]=(long)(m[a]*UNIT);
	}

	#if 0
	printf("\ndet:%10lf\n",det);
	for(y=0;y<3;y++) 
	{
		printf("d[] ");
		for(x=0;x<3;x++) 
		{
			printf("%6.3lf ",d[x+y*3]);
		}
		printf("\n");
	}
	for(y=0;y<3;y++) 
	{
		for(x=0;x<3;x++) 
		{
			printf("%6.3lf ",m0[x+y*3]);
		}
		printf("* ");
		for(x=0;x<3;x++) 
		{
			printf("%6.3lf ",m[x+y*3]);
		}
		printf("= ");
		for(x=0;x<3;x++) 
		{
			det=m[x+0*3]*m0[0+y*3]+m[x+1*3]*m0[1+y*3]+m[x+2*3]*m0[2+y*3];
			printf("%6.3lf ",det);
		}
		printf("\n");
	}
	printf("\n");
	#endif
	return((int)(UNIT*det));
}
예제 #12
0
quest18::Print(TList* plist, class test &t)
{
        int i, j, k;
        int p[4], a[3], b[3], c[3];
        int M[3], matr[2][2];
        int n, Right_Numb;

        double absc, absa;

        drobi d;

        char * buf = new char[256];
        char * buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        Right_Numb = random( 5 ) + 1;

        srand( keygen );

        for( i = 0; i < 4; i ++ )
        {
                a[i] = rgen( keygen, 1, amin, amax );
                M[i] = rgen( keygen, 1, amin, amax );
                p[i] = rgen( keygen, 1, amin, amax );

                while ( p[i] == M[i] )
                        p[i] = rgen( keygen, 1, amin, amax );
        }

        sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Найти расстояние от точки до прямой.)" );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Прямая задана уравнением:)" );
        plist->Add( strdup(buf) );

        if( M[0] )
                sprintf( buf, "(x%+d)/%d=", -M[0], a[0] );
        else
                sprintf( buf, "x/%d=", a[0] );

        if( M[1] )
                sprintf( buf1, "(y%+d)/%d=", -M[1], a[1] );
        else
                sprintf( buf1, "y/%d=", a[1] );
        strcat( buf, buf1 );

        if( M[2] )
                sprintf( buf1, "(z%+d)/%d", -M[2], a[2] );
        else
                sprintf( buf1, "z/%d", a[2] );

        strcat( buf, buf1 );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Координаты точки:)" );
        plist->Add( strdup(buf) );

        sprintf( buf, "A!(%d", p[0] );

        for( i = 1; i < 3; i ++ )
        {
                sprintf( buf1, ",%d", p[i] );
                strcat( buf, buf1 );
        }

        strcat( buf, ")" );
        plist->Add( strdup(buf) );

        sprintf( buf, "d=..." );
        plist->Add( strdup(buf) );

        for ( i = 0; i < 3; i++ )
                b[i] = M[i] - p[i];

        for (i = 0; i < 3; i ++)
        {
                k = 0;

                for ( j = 0; j < 3; j ++ )
                {
                        if ( j != i )
                        {
                                matr[0][k] = a[j];
                                matr[1][k] = b[j];
                                k ++;
                        }
                }

                c[i] = pow ( -1, i ) * determ( 2, matr );
        }

        absc = 0;

        for ( i = 0; i < 3; i ++ )
                absc += c[i] * c[i];

        absa = 0;

        for ( i = 0; i < 3; i ++ )
                absa += a[i] * a[i];

        if( absc < 5 )
                Right_Numb = 1;

        for( n = 0; n < 5; n ++ )
        {
                sprintf( buf, "String(\"Вариант %c):\")", 'a' + n );
                plist->Add( strdup(buf) );

                if ( !( absc - ( Right_Numb - 1 ) + n ) )
                        sprintf( buf, "d=0" );
                else
                if ( ( ceil( sqrt( absc - ( Right_Numb - 1 ) + n ) ) ) == ( sqrt( absc - ( Right_Numb - 1 ) + n ) ) && ( ceil( sqrt( absa ) ) ) == ( sqrt( absa ) ) )
                {
                        d = drobi( sqrt( absc - ( Right_Numb - 1 ) + n ), sqrt( absa ) );
                        //sprintf( buf, "d=%d/%d", d.a, d.b );
                        sprintf( buf, "d=%s", DrobiToStr( d ) );
                }
                else
                if ( ( ceil( sqrt( absc - ( Right_Numb - 1 ) + n ) ) ) == ( sqrt( absc - ( Right_Numb - 1 ) + n ) ) )
                        sprintf( buf, "d=%f/sqrt(%f)", sqrt( absc - ( Right_Numb - 1 ) + n ), absa );
                else
                if ( ( ceil( sqrt( absa ) ) ) == ( sqrt( absa ) ) )
                        sprintf( buf, "d=sqrt(%f)/%f", absc - ( Right_Numb - 1 ) + n, sqrt( absa ) );
                else
                        sprintf( buf, "d=sqrt(%f)/sqrt(%f)", absc - ( Right_Numb - 1 ) + n, absa );

                plist->Add( strdup(buf) );
        }

        /*sprintf(buf,"String(@Часть преподавателя )");
        plist->Add(strdup(buf));

        sprintf(buf,"String(\"Тема - %s \")",selecttask->name);
        plist->Add(strdup(buf));

        sprintf(buf,"String(ВАРИАНТ   %i, решение задачи %i, ключ %i)", nvar, nzad, keygen );
        plist->Add(strdup(buf));

        sprintf(buf,"String( Правильный ответ - %c)", 'a' + Right_Numb - 1 );
        plist->Add(strdup(buf));*/

        t.pr_tst = 1;
        t.ch_ask = 5;
        t.right_ask = Right_Numb;
        t.msg = "Тест успешно сгенерирован.";

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}
예제 #13
0
파일: fit_acf.c 프로젝트: asreimer/VTRST3.5
int fit_acf (struct complex *acf,int range,
             int *badlag,struct FitACFBadSample *badsmp,int lag_lim,
			 struct FitPrm *prm,
		     double noise_lev_in,char xflag,double xomega,
		     struct FitRange *ptr,int print) {

  double sum_np,sum_w,sum_wk,sum_wk2,*sum_wk2_arr=NULL,sum_wk4;
  double sum_p,sum_pk,sum_pk2,sum_phi,sum_kphi;
  double t0,t2,t4,*phi_res=NULL;
  int j;
  long k;
  int npp;
  double *tau=NULL, *tau2=NULL;
  double *phi_k=NULL; 
  double *w=NULL, *pwr=NULL;
  double *wt=NULL, *wt2=NULL, *wp=NULL;
  double e2;

  double c_log,c_log_err,d;
  double omega_loc, omega_err_loc, phi_loc, noise_lev;
  double omega_base, omega_high, omega_low;
  double phase_sdev;
  double temp;
  double phi_err, omega_err;
  double wbar;

  int s=0;


/*  The following variables have been added for version 2.0 of cfitacf */

  double /*P0, */ P0n;   /* this is the power level where the acf levels off */
  int last_good;
  int *bad_pwr=NULL;

  int status;

/* the following array has been added to support preprocessing of the
   acf */

  int acf_stat=ACF_UNMODIFIED;

	if(print && prm->channel < 2)
		fprintf(stdout,"%d  %lf\n",range-1,acf[0].x/sqrt(1.0*prm->nave));


/* ----------------End of declarations ----------------------------------*/
 
  if (cabs(acf[0]) < noise_lev_in) {
    for (j=0; j<prm->mplgs; j++) badlag[j]=3;
    ptr->p_l = 0.0;
    ptr->p_s = 0.0;
    ptr->p_l_err = 0.0;
    ptr->p_s_err = 0.0;
    ptr->v = 0.0;
    ptr->v_err = 0.0;
    ptr->w_l = 0.0;
    ptr->w_l_err = 0.0;
    ptr->w_s = 0.0;
    ptr->w_s_err = 0.0;
    ptr->phi0 = 0.0;
    ptr->phi0_err = 0.0;
    ptr->sdev_l = 0.0;
    ptr->sdev_s = 0.0;
    return 2;
  }


  /* allocate buffers */

  sum_wk2_arr=malloc(sizeof(double)*prm->mplgs);
  if (sum_wk2_arr==NULL) s=-1;
  if (s==0) phi_res=malloc(sizeof(double)*prm->mplgs);
  if (phi_res==NULL) s=-1;
  if (s==0) tau=malloc(sizeof(double)*prm->mplgs);
  if (tau==NULL) s=-1;
  if (s==0) tau2=malloc(sizeof(double)*prm->mplgs);
  if (tau2==NULL) s=-1;
  if (s==0) phi_k=malloc(sizeof(double)*prm->mplgs);
  if (phi_k==NULL) s=-1;
  if (s==0) w=malloc(sizeof(double)*prm->mplgs);
  if (w==NULL) s=-1;
  if (s==0) pwr=malloc(sizeof(double)*prm->mplgs);
  if (pwr==NULL) s=-1;
  if (s==0) wt=malloc(sizeof(double)*prm->mplgs);
  if (wt==NULL) s=-1;
  if (s==0) wt2=malloc(sizeof(double)*prm->mplgs);
  if (wt2==NULL) s=-1;
  if (s==0) wp=malloc(sizeof(double)*prm->mplgs);
  if (wp==NULL) s=-1;
  if (s==0) bad_pwr=malloc(sizeof(int)*prm->mplgs);
  if (bad_pwr==NULL) s=-1;

  if (s !=0) {
    if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
    if (phi_res !=NULL)  free(phi_res);
    if (tau !=NULL) free(tau);
    if (tau2 !=NULL) free(tau2);
    if (phi_k !=NULL) free(phi_k);
    if (w !=NULL) free(w);
    if (pwr !=NULL) free(pwr);
    if (wt !=NULL) free(wt);
    if (wt2 !=NULL) free(wt2);
    if (wp !=NULL) free(wp);
    if (bad_pwr !=NULL) free(bad_pwr);
		if(print && prm->channel < 2)
				fprintf(stdout,"-1\n");
    return -1;
  }

  /* initialize the table of abs(acf[k]) and log(abs(acf[k])) */


	if(print && prm->channel < 2)
				fprintf(stdout,"0\n");

  FitACFCkRng(range, badlag, badsmp, prm);

	if(print && prm->channel < 2)
	{
		int availflg,lag;
		for(j=0;j<prm->mplgs;j++)
		{
			/*tauscan, new ROS*/
			if((prm->cp == 3310 || prm->cp == 503 || prm->cp == -503) && prm->mplgs == 18) lag = j;
			/*old ROS*/
			else lag = abs(prm->lag[0][j] - prm->lag[1][j]);

			if(badlag[j] != 0)
				availflg = 0;
			else
				availflg = 1;

			fprintf(stdout,"%d  %lf  %lf  %d\n",lag,acf[j].x,acf[j].y,badlag[j]);
		}
	}

  /* Save the original ACF in a new variable so we can try some
     preprocessing on it.
  */

/*  for (k=0; k < prm->mplgs; k++) {
    orig_acf[k].x = acf[k].x;
    orig_acf[k].y = acf[k].y;
  }
*/

  /* This next statement provides a hook for a routine to pre-process
    the ACF and return a modified ACF that will actually be fitted.

    The function acf_preproc should return a 0 if no change was made
    and a non-zero value otherwise - the actual non-zero value may be
    used to provide information about the change that was made.  Specifically
    the following values should be defined:
	   ACF_UNMODIFIED	  the ACF was unchanged
       ACF_GROUND_SCAT    the preprocessing indicates the ACF is ground
	   						scatter.
	   ACF_ION_SCAT		  the preprocessing indicates the ACF is Ionospheric
	   ACF_MIXED_SCAT	  the preprocessing indicates a mixture of
	   						ionospheric and ground scatter.

    The original acf will be in the array "orig_acf" and the modified
    acf will be in "acf".

    To write an acf_preprocessor you must use the calling convention below.
    The revised acf will be returned in the array acf.  You must also provide
    the value of the noise_level (noise_lev_in), the range number, the badlag
    table, and the number of lags
  */

  noise_lev = noise_lev_in;
/*
  if (noise_lev != 0.0) acf_stat = acf_preproc (acf, orig_acf, &noise_lev,
			range, badlag, prm->mplgs);
*/
  for (k=0; k<prm->mplgs; k++) {
    tau[k] = prm->lag[1][k] - prm->lag[0][k];
    tau2[k] = tau[k] * tau[k];
    w[k] = cabs(acf[k]); /* w[k] = cabs(acf[k])- noise_lev; */
     if (w[k] <= noise_lev) w[k] = 0.1; /* if (w[k] <= 0.0) w[k] = 0.1; */
  }

  /* we now have to compute the amount of power to subtract off the 
   power level at each range.  The amouont to be subtracted is P(0)/sqrt(nave)
   which is the approximate expectation value of the power level after the
   ACF has decorrelated. 

   [ To derive this, determine the expectation value of
   P**2 = R(tau)*conj(R(tau))]
  */

  P0n = w[0]/sqrt((double) prm->nave);


  if ((w[0] - P0n) < noise_lev) {
    if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
    if (phi_res !=NULL)  free(phi_res);
    if (tau !=NULL) free(tau);
    if (tau2 !=NULL) free(tau2);
    if (phi_k !=NULL) free(phi_k);
    if (w !=NULL) free(w);
    if (pwr !=NULL) free(pwr);
    if (wt !=NULL) free(wt);
    if (wt2 !=NULL) free(wt2);
    if (wp !=NULL) free(wp);
    if (bad_pwr !=NULL) free(bad_pwr);
		if(print && prm->channel < 2)
				fprintf(stdout,"1\n");
    return 2; 
  } 
    /* give up if left over pwr is too low */

	if(print && prm->channel < 2)
			fprintf(stdout,"0\n");

  /*  identify any additional bad lags */

  sum_np = more_badlags(w, badlag, noise_lev, prm->mplgs,prm->nave);

	if(print && prm->channel < 2)
	{
		int availflg,lag;
		for(j=0;j<prm->mplgs;j++)
		{
			/*tauscan, new ROS*/
			if((prm->cp == 3310 || prm->cp == 503 || prm->cp == -503) && prm->mplgs == 18) lag = j;
			/*old ROS*/
			else lag = abs(prm->lag[0][j] - prm->lag[1][j]);

			if(badlag[j] != 0)
				availflg = 0;
			else
				availflg = 1;

			fprintf(stdout,"%d  %lf  %lf  %d\n",lag,acf[j].x,acf[j].y,badlag[j]);
		}
	}

  ptr->nump = (char) sum_np;

  /*  We must have at least lag_lim good lags */

  if (sum_np < lag_lim) {
    if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
    if (phi_res !=NULL)  free(phi_res);
    if (tau !=NULL) free(tau);
    if (tau2 !=NULL) free(tau2);
    if (phi_k !=NULL) free(phi_k);
    if (w !=NULL) free(w);
    if (pwr !=NULL) free(pwr);
    if (wt !=NULL) free(wt);
    if (wt2 !=NULL) free(wt2);
    if (wp !=NULL) free(wp);
    if (bad_pwr !=NULL) free(bad_pwr);
		if(print && prm->channel < 2)
			fprintf(stdout,"4\n");
    return 4;
  }

  if (noise_lev <= 0.0) noise_lev = 0.1; 
    /* this is required to make logs ok */
  w[0]=w[0]-prm->noise; /* This is to remove background delta-correlated noise from lag 0 power (version 2.0)*/

  /* OK, now we have determined the good lags for the phase fit.  
     Now subtract of P0n from the power profile */

  /* calculate the power values for each lag.  'w' is the linear power.
     wt is the power times the lag.  wt2 is power times lag**2.  
     pwr is the log of the power. wp is the linear power times the log of
     the power.  The items that involve the linear power are all parts of 
     the least squares fits with the weighting done by the linear power. */

  for (k=0; k<prm->mplgs; k++) {
 
    if (w[k] <= P0n) w[k] = 0.1; /* if (w[k] <= 0.0) w[k] = 0.1; */
    wt[k] = w[k]*w[k]*tau[k];
    wt2[k] = wt[k]*tau[k];
    pwr[k] = log(w[k]);
    wp[k] = w[k]*w[k]*pwr[k];
  }
  /* we now have to check to see how many additional bad lags have been
     introduced by subtracting off P0n. */

  for (k=0, npp=0; k < prm->mplgs; k++) {
    if (w[k] < noise_lev+P0n && !badlag[k]) bad_pwr[k] = 1; /* if (w[k] < noise_lev && !badlag[k]) bad_pwr[k] = 1; */
    else bad_pwr[k] = 0;
    if (! (badlag[k] || bad_pwr[k])) ++npp;
  }

 /* initialize the sums */

  sum_np = 1;
  sum_w = w[0]*w[0];
  sum_wk = 0;
  sum_wk2 = 0;
  sum_wk2_arr[0] = 0;
  sum_wk4 = 0;
  sum_p = w[0]*w[0]*pwr[0];
  sum_pk = 0;
  sum_pk2 = 0;
  phi_loc = atan2(acf[0].y, acf[0].x);
  sum_kphi = 0;
  t0 =  prm->mpinc * 1.0e-6;
  t2 = t0 * t0;
  t4 = t2 * t2;

  /* calculate all the residual phases */
  /* if calc_phi_res returns a bad status abort the fit */

  if (calc_phi_res(acf, badlag, phi_res, prm->mplgs) != 0){
    if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
    if (phi_res !=NULL)  free(phi_res);
    if (tau !=NULL) free(tau);
    if (tau2 !=NULL) free(tau2);
    if (phi_k !=NULL) free(phi_k);
    if (w !=NULL) free(w);
    if (pwr !=NULL) free(pwr);
    if (wt !=NULL) free(wt);
    if (wt2 !=NULL) free(wt2);
    if (wp !=NULL) free(wp);
    if (bad_pwr !=NULL) free(bad_pwr);
		if(print && prm->channel < 2)
			fprintf(stdout,"2\n");
    return 2;
  }

  if (!xflag) {
    if (acf_stat == ACF_GROUND_SCAT) omega_loc = 0.0;
    else omega_loc = omega_guess(acf, tau, badlag, phi_res, 
				 &omega_err_loc,prm->mpinc,prm->mplgs);
    phi_k[0] = 0;
    sum_phi = 0;
  } else {
    phi_k[0] = phi_loc;
    sum_phi = phi_loc * w[0]*w[0];
    omega_loc = xomega;
  }


  /*  The preliminaries are now over.  
  Now start the fitting process */

  /* first, calculate the sums needed for the phase fit */

  for (k=1; k<prm->mplgs; k++) {
    if (badlag[k]) {
      sum_wk2_arr[k] = sum_wk2_arr[k-1];
      continue;
    }
    sum_w = sum_w + w[k]*w[k];
    sum_np = sum_np + 1;
    sum_wk = sum_wk + w[k]*w[k]*tau[k];
    sum_wk2 = sum_wk2 + wt2[k];
    sum_wk2_arr[k] = sum_wk2;
  }

  /* Now do the phase fit using the best initial guess for omega */

 
  status = do_phase_fit (omega_loc, xflag, prm->mplgs, acf, tau,
			 w, sum_wk2_arr, phi_res, badlag, t0,
			 sum_w, sum_wk, sum_wk2,
			 &omega_base, &phi_loc, &phase_sdev,
			 &phi_err, &omega_err);

  ptr->phi0 = phi_loc;
  ptr->v = omega_base;
  ptr->sdev_phi = phase_sdev;
  ptr->phi0_err = phi_err;
  ptr->v_err = omega_err;

  /* check the status of the phase fit to see if it was actually OK.  
     if not, set error bars to HUGE_VAL */

  if (status != 0) {
    ptr->sdev_phi = HUGE_VAL;
    ptr->v_err = HUGE_VAL;
    if (xflag) ptr->phi0_err = HUGE_VAL;
  }
  
  /* OK, we now have our baseline value for omega.  Now re-do the
     phase fit, but using omega_loc + omega__err_loc. */


  if (!xflag && (status == 0)) {
  status = do_phase_fit (omega_loc + omega_err_loc,
                         xflag, prm->mplgs, acf, tau,
			 w, sum_wk2_arr, phi_res, badlag, t0,
			 sum_w, sum_wk, sum_wk2,
			 &omega_high, &phi_loc, &phase_sdev,
			 &phi_err, &omega_err);

  status = do_phase_fit (omega_loc - omega_err_loc, 
                         xflag, prm->mplgs, acf, tau,
			 w, sum_wk2_arr, phi_res, badlag, t0,
			 sum_w, sum_wk, sum_wk2,
			 &omega_low, &phi_loc, &phase_sdev,
			 &phi_err, &omega_err);

  /* if the difference between the high and low values of omega
     is greater than the error estimate of the original fit,
     we will use the original fit as our best guess for the
     velocity, but we'll set the error to be the difference between
     the high and low values.  Actually, at this point we should have
     non-symmetric error bar, but the file format has no provision 
     for that. */

  if (fabs(omega_high - omega_low) >= 2*ptr->v_err) {
    ptr->v = omega_base;
    ptr->v_err = fabs(omega_high - omega_low);
    }
  }
  

  /* POWER FITS:  We now turn to the power fits.  The sums have to be
  partially redone, since we have subtracted P0n. */

  /* We are now faced with the question of what to do if we don't have enough 
  lags left to do a fit.  we can't abaondon the data because the phase fit is
  actually ok.  we have to have at least 3 points to do the fit and estimate 
  an error on the fit.

  If we don't have at least 3 good points, then simply set the lamda and
  sigma powers both to the power_lag0 level.  If there are only 2 good points
  then calculate the value of sigma and lamda, but set the error estimate
  to HUGE_VAL.

  If we end up with only lag-0 being good, then flag the width estimate
  by setting it to a large negative value.

*/

  if (npp < 3) {
    c_log = pwr[0];

    /* if c_log < 0 it means that after subtracting the noise and P0n,
     the result is less than 1.0.  This must really be pretty meaningless
     It shouldn't even be possible since we have supposedly already checked
     this at the beginning. */

    if (c_log < 0 ) {
      if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
      if (phi_res !=NULL)  free(phi_res);
      if (tau !=NULL) free(tau);
      if (tau2 !=NULL) free(tau2);
      if (phi_k !=NULL) free(phi_k);
      if (w !=NULL) free(w);
      if (pwr !=NULL) free(pwr);
      if (wt !=NULL) free(wt);
      if (wt2 !=NULL) free(wt2);
      if (wp !=NULL) free(wp);
      if (bad_pwr !=NULL) free(bad_pwr);
			if(print && prm->channel < 2)
				fprintf(stdout,"3\n");
      return 2;
    }

		

    ptr->p_l = c_log;
    ptr->p_s = c_log;

    /* find the last good lag */
    last_good = -1;
    for (k= 0; k < prm->mplgs; k++) if (!badlag[k]) last_good = k;

    /* if there are no good lags, or only lag-0 is good, set the width
       to a high negative value, by setting the last_good lag to 1
       */

    if (last_good <=0 ) {
  	  ptr->w_l = -9999.0;
	  ptr->w_s = -9999.0;
	  ptr->p_l_err = HUGE_VAL;
	  ptr->p_s_err = HUGE_VAL;
	  ptr->w_l_err = HUGE_VAL;
	  ptr->w_s_err = HUGE_VAL;
	  ptr->sdev_l = HUGE_VAL;
	  ptr->sdev_s = HUGE_VAL;
    } else {
      /* now calculate the width as the lag-0 power divided by the
       time to the last good lag. */

      ptr->w_l = c_log/(tau[last_good]*t0);
      ptr->w_s = c_log/(tau2[last_good]*t2);

      /* set the errors to the maximum value */

      ptr->p_l_err = HUGE_VAL;
      ptr->p_s_err = HUGE_VAL;
      ptr->w_l_err = HUGE_VAL;
      ptr->w_s_err = HUGE_VAL;
      ptr->sdev_l = HUGE_VAL;
      ptr->sdev_s = HUGE_VAL;
    }
  } else {
    /*  Calculate the sums that were not used in the phase fit */
    for (k=1; k < prm->mplgs; k++) {
	  if (badlag[k] || bad_pwr[k]) continue;
	  sum_p = sum_p + wp[k];
	  sum_pk = sum_pk + pwr[k]*wt[k];
	  sum_pk2 = sum_pk2 + pwr[k]*wt2[k];
	  sum_wk4 = sum_wk4 + wt2[k]*tau2[k];
    }

    /* Now adjust the sums that were used in the phase fit, but that
       have changed because of additional bad lags */

    for (k=1; k< prm->mplgs; k++) {
	  if (bad_pwr[k]) {
	    sum_w = sum_w - w[k]*w[k];
	    sum_np = sum_np - 1;
	    sum_wk = sum_wk - w[k]*w[k]*tau[k];
	    sum_wk2 = sum_wk2 - wt2[k];
  	  }
    }
    
/*  start with the lamda fit */

    d = determ(sum_w,-t0*sum_wk,t0*sum_wk,-t2*sum_wk2);
    c_log = determ(sum_p,-t0*sum_wk,t0*sum_pk,-t2*sum_wk2)/d;

    ptr->p_l = c_log;

    ptr->w_l = determ(sum_w,sum_p,t0*sum_wk,t0*sum_pk)/d;

    if (sum_np > 3) {
	  e2 = 0.;
	  wbar = 0.;
	  npp = 0;
	  for (k=0; k<prm->mplgs; k++)
	    if ((badlag[k] == 0) && (bad_pwr[k] == 0)) {
		  temp = pwr[k] - (c_log - tau[k]*t0* (ptr->w_l));
		  e2 = e2 + w[k]*w[k]*(temp*temp);
		  wbar = wbar + w[k];
		  npp++;
	    }
	  wbar = wbar/npp;
	  ptr->sdev_l = sqrt(e2/sum_w/(npp - 2));

	  if ((sum_w*sum_wk2 - sum_wk*sum_wk) <=0) {
	    ptr->p_l_err = HUGE_VAL;
	    ptr->w_l_err = HUGE_VAL;
	    ptr->sdev_l = HUGE_VAL;
	  } else {
	    c_log_err = ptr->sdev_l * wbar *
		sqrt(sum_wk2/(sum_w*sum_wk2 - sum_wk*sum_wk));
	    ptr->p_l_err = c_log_err;

	    ptr->w_l_err = ptr->sdev_l * wbar *
		 sqrt(sum_w/(t2*(sum_w*sum_wk2 -
                         sum_wk*sum_wk)));
	  }
    } else {
	  ptr->p_l_err = HUGE_VAL;
	  ptr->w_l_err = HUGE_VAL;
	  ptr->sdev_l = HUGE_VAL;
    }
    

/* ----------------now do the sigma fit ------------------------ */

    d = determ(sum_w,-t2*sum_wk2,t2*sum_wk2,-t4*sum_wk4);
    c_log = determ(sum_p,-t2*sum_wk2,t2*sum_pk2,-t4*sum_wk4)/d;

    ptr->p_s = c_log;

    ptr->w_s = determ(sum_w,sum_p,t2*sum_wk2,t2*sum_pk2)/d;

    if (sum_np > 3) {	
	  e2 = 0.;
	  wbar = 0.;
	  npp = 0;
	  for (k=0; k<prm->mplgs; k++)
	    if ((badlag[k] == 0) && (bad_pwr[k] == 0)) {
		  temp = pwr[k] - (c_log - tau2[k]*t2* (ptr->w_s)); 
		  e2 = e2 + w[k]*w[k]*(temp*temp);
		  wbar = wbar + w[k];
		  npp++;
	    }
	  wbar = wbar/npp;
	  ptr->sdev_s = sqrt(e2/sum_w/(npp - 2));

	  if ((sum_w*sum_wk4 - sum_wk2*sum_wk2) <= 0.0 ) {
	    ptr->p_s_err = HUGE_VAL;
	    ptr->w_s_err = HUGE_VAL;
	    ptr->sdev_s = HUGE_VAL;
	  } else {
	    c_log_err = ptr->sdev_s * wbar *
	      sqrt(sum_wk4/(sum_w*sum_wk4 - sum_wk2*sum_wk2));
	    ptr->p_s_err = c_log_err;	    
	    ptr->w_s_err = ptr->sdev_s * wbar * 
	       sqrt(sum_w/(t4*(sum_w*sum_wk4 - sum_wk2*sum_wk2)));


	  }
    } else {
	  ptr->p_s_err = HUGE_VAL;
	  ptr->w_s_err = HUGE_VAL;
	  ptr->sdev_s = HUGE_VAL;
    }	

    /* finally check for ground scatter fit */

    /*  first, see if an ACF preprocessor has already identified the
  	  scatter as being ground scatter.  */
	
    if (acf_stat == ACF_GROUND_SCAT) ptr->gsct = 1; 
    else {
      ptr->gsct = 0;
    }
  }

	if(print && prm->channel < 2)
	{
		fprintf(stdout,"0\n");
		fprintf(stdout,"%lf\n",omega_loc);
	}

  if (sum_wk2_arr !=NULL) free(sum_wk2_arr);
  if (phi_res !=NULL)  free(phi_res);
  if (tau !=NULL) free(tau);
  if (tau2 !=NULL) free(tau2);
  if (phi_k !=NULL) free(phi_k);
  if (w !=NULL) free(w);
  if (pwr !=NULL) free(pwr);
  if (wt !=NULL) free(wt);
  if (wt2 !=NULL) free(wt2);
  if (wp !=NULL) free(wp);
  if (bad_pwr !=NULL) free(bad_pwr);
 
  /* all done - return code = 1 */
  if (npp < 1) return 4;
  else return 1;
}
예제 #14
0
int do_phase_fit (double omega_guess, 
		  char xflag, 
		  int mplgs,
		  struct complex *acf,
		  double *tau,
		  double *w,
		  double *sum_wk2_arr,
		  double *phi_res,
		  int *badlag,
		  double t0,
		  double sum_w,
		  double sum_wk,
		  double sum_wk2,
		  
		  double *omega,
		  double *phi0,
		  double *sdev,
		  double *phi0_err,
		  double *omega_err
		  )
{
  /*  local declarations */

  double omega_loc, omega_init;
  double omega_old_2=9999.0, omega_old = 9999.0;
  int icnt = 0;

  double phi_loc = 0.0;
  double sum_phi = 0.0;
  double sum_kphi = 0.0;
  double phi_pred;
  double phi_tot;
  double *phi_k=NULL;
  double t2;
  double wbar;
  double phitmp,phifrc,phiint;
  int n_twopi;
  int nphi;
  int k;

  double d=0.0, e2;

  omega_loc = omega_guess;
  t2 = t0*t0;

  phi_k=malloc(sizeof(double)*mplgs);
  if (phi_k==NULL) return -1;

  for (k=0;k<mplgs;k++) phi_k[k]=0;

  while (fabs(omega_old - omega_loc) > fabs(omega_loc * PI/64.)) {

    /* if omega_loc == omega_old_2 it means we are oscillating between
       two different values of omega */

    if ((icnt>0) && (omega_loc == omega_old_2)) {
      *omega = (omega_old + omega_loc)/2.;
      /* return the average value of the two omega values and return
	 with error code 16 */
      *phi0 = phi_loc;
      free(phi_k);
      return 16;
    }

    /* if icnt >= 5 it means we aren't converging on a stable value for
       omega */

    if (++icnt >= 5) {
      /* return whatever we have at this moment
	 and set error code 32 */
      *omega = omega_loc;
      *phi0 = phi_loc;
      free(phi_k);
      return 32;
    }

    omega_old_2 = omega_old;
    omega_old = omega_loc;
    omega_init = omega_loc;

    if (!xflag) phi_loc = 0.;

    sum_phi = atan2(acf[0].y,acf[0].x);
    sum_phi = sum_phi*w[0]*w[0];
    sum_kphi = 0.0;
    n_twopi = 0;
    nphi = 0;

    /* now go through the point, one at a time, predicting the new
       value for phi_tot from the current best value for omega */

    for (k=1; k<mplgs; k++) {
      if (badlag[k]) continue;
      phi_pred = phi_loc + omega_loc*tau[k]*t0;
   
      /* The code for calculating n_twopi had a problem, the conversion to
         an integer sometimes produded the wrong result
      */

     
      phitmp =((PI + phi_pred - phi_res[k])/(2*PI) - 
		((omega_loc > 0) ? 0.0 : 1.0));

      phifrc=modf(phitmp,&phiint);
      n_twopi=(int) phiint;            
      if (phifrc>0.5) n_twopi++;
      if (phifrc<-0.5) n_twopi--;


      phi_tot = phi_res[k] + n_twopi*(2*PI);


      if (fabs(phi_pred - phi_tot) > PI) {
	    if (phi_pred > phi_tot) phi_tot = phi_tot + 2*PI;
	    else phi_tot = phi_tot - 2*PI;
      }
      

      phi_k[k] = phi_tot;
      sum_phi = sum_phi + phi_tot*w[k]*w[k];
      sum_kphi = sum_kphi + tau[k]*phi_tot*w[k]*w[k];
      ++nphi;

      /* if this is the first time through the omega fit loop AND
  	  we are doing ACFs, NOT xcfs, and we've got enough points to
	  draw a line, THEN compute a new value of omega_loc as we add each
	  new point */

      if (!xflag && sum_wk2_arr[k] && (omega_old_2 == 9999.)) {
	    omega_loc = sum_kphi/(t0*sum_wk2_arr[k]);
	    omega_loc = (nphi*omega_loc + omega_init)/(nphi + 1);
      }
    }

    if (xflag) {
      d = determ(sum_w,sum_wk*t0,sum_wk*t0,sum_wk2*t2);
      if (d == 0) {
        free(phi_k);
        return 8;
      }
      phi_loc = determ(sum_phi,sum_wk*t0,sum_kphi*t0,sum_wk2*t2)/d;
      omega_loc = determ(sum_w,sum_phi,sum_wk*t0,sum_kphi*t0)/d;
    } else {
      phi_loc = 0;
      if (sum_wk2 <= 0.0) {
        free(phi_k);
        return 8;
      }
      omega_loc = sum_kphi/(t0*sum_wk2);
    }
  }
  /*  End of While loop */

  if (phi_loc > PI) phi_loc = phi_loc - 2*PI;

  *phi0 = phi_loc;
  *omega = omega_loc;

  /* Now we calculate the estimated error of the fit */

  wbar = 0;
  e2 = 0.;
  nphi = 0;
  for (k=0; k<mplgs; k++) {
    if (!badlag[k]) {
	    e2 += w[k]*w[k]*(phi_k[k] - phi_loc - omega_loc*tau[k]*t0)*
             (phi_k[k] - phi_loc - omega_loc*tau[k]*t0);
	    wbar += w[k];
	    nphi++;
    }
  }
  wbar = wbar/nphi;
  if (xflag) *sdev = sqrt(e2/(sum_w)/(nphi-2));
  else *sdev = sqrt(e2/sum_w/(nphi-1));

  if (xflag) {
    *phi0_err =  *sdev * wbar * sqrt(sum_wk2*t2/d);
    *omega_err = *sdev * wbar * sqrt(sum_w/d);
  }
  else {
    *phi0_err = 0;
    *omega_err = *sdev*wbar/sqrt(sum_wk2)/t0;
  }
  free(phi_k);
  return 0;
}
예제 #15
0
quest24::Print(TList* plist)
{
        drobi mtr[10][10];

        int i, j, k, l, n;
        int ma[10][10], A[10][10];
        int det_A, det_B;

        char* buf = new char[256];
        char* buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        srand( keygen );

        for( i = 0; i < dim; i++ )
        {
                for( j = 0; j < dim; j++ )
                {
                        ma[i][j] = 0;
                }
        }

        while( !determ( dim, ma ) )
        for( i = 0; i < dim; i++ )
        {
                for( j = 0; j < dim; j++ )
                {
                        ma[i][j] = rgen( keygen, 1, amin, amax );
                }
        }

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
                plist->Add( strdup(buf) );
        }
        else
        {
                sprintf( buf, "String(#)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        if ( !qvar->MZad || ( qvar->MZad && nvar == 1 ) )
        {
                sprintf( buf, "String(Найти обратную матрицу к матрице:)" );
                plist->Add( strdup(buf) );
        }

        sprintf( buf, "A=!(Matrix(%d,%d", dim, dim );

        for ( i = 0; i < dim; i ++ )
        for ( j = 0; j < dim; j ++ )
        {
                sprintf( buf1, ",%d", ma[i][j] );
                strcat( buf, buf1 );
        }

        strcat( buf, "))" );
        plist->Add( strdup(buf) );

        sprintf( buf, "pow(A,-1)=..." );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(@Часть преподавателя )" );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(\"Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(ВАРИАНТ   %i, решение задачи %i, ключ %i)", nvar, nzad, keygen );
        plist->Add( strdup(buf) );

        det_A = determ ( dim, ma );

        for ( i = 0; i < dim; i ++ )
        for ( j = 0; j < dim; j ++ )
        {
                int ai, aj;

                ai = 0;
                aj = 0;

                for ( k = 0; k < dim; k ++ )
                {
                        if ( k == j )
                                continue;
                        else
                        {
                        for ( l = 0; l < dim; l ++ )
                        {
                                if ( l != i )
                                {
                                        A[ai][aj] = ma[k][l];
                                        aj ++;
                                }
                                else
                                        continue;
                        }
                                ai ++;
                                aj = 0;
                        }
                }

                mtr[i][j] = drobi ( pow( -1, i + j ) * determ( dim - 1, A ), det_A );
                mtr[i][j].sokrat();
        }

        sprintf( buf, "pow(A,-1)=!(Matrix(%d,%d", dim, dim );

        for ( i = 0; i < dim; i ++ )
        for ( j = 0; j < dim; j ++ )
        {
                sprintf( buf1, ",%s", DrobiToStr( mtr[i][j] ) );
                strcat( buf, buf1 );
        }

        strcat( buf, "))" );
        plist->Add( strdup(buf) );

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}
예제 #16
0
quest24::Print(TList* plist, class test &t)
{
        drobi mtr[10][10];

        int i, j, k, l, n;
        int ma[10][10], A[10][10];
        int det_A, det_B;
        int Right_Numb;

        char* buf = new char[256];
        char* buf1 = new char[256];

        if( keygen == 0 )
        {
                keygen = random( 1000 ) + 1;
        }

        srand( keygen );

        Right_Numb = random( 5 ) + 1;

        for( i = 0; i < dim; i++ )
        {
                for( j = 0; j < dim; j++ )
                {
                        ma[i][j] = 0;
                }
        }

        while( !determ( dim, ma ) )
        for( i = 0; i < dim; i++ )
        {
                for( j = 0; j < dim; j++ )
                {
                        ma[i][j] = rgen( keygen, 1, amin, amax);
                }
        }

        sprintf( buf, "String(\"# Тема - %s \")", selecttask->name );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Вариант   %i, задача %i.)", nvar, nzad );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Найти обратную матрцу к матрице:)" );
        plist->Add( strdup(buf) );

        sprintf( buf, "A=!(Matrix(%d,%d", dim, dim );

        for ( i = 0; i < dim; i ++ )
        for ( j = 0; j < dim; j ++ )
        {
                sprintf( buf1, ",%d", ma[i][j] );
                strcat( buf, buf1 );
        }

        strcat( buf, "))" );
        plist->Add( strdup(buf) );

        sprintf( buf, "pow(A,-1)=..." );
        plist->Add( strdup(buf) );

        sprintf( buf, "String(Варианты ответов: )" );
        plist->Add( strdup(buf) );

        for ( n = 0; n < 5; n ++ )
        {
                sprintf( buf, "String(\"Вариант %c):\")", 'a' + n );
                plist->Add( strdup(buf) );

                det_A = determ ( dim, ma );

                if ( n != Right_Numb - 1 )
                        det_A = det_A + ( random ( 20 ) - 10 );

                for ( i = 0; i < dim; i ++ )
                for ( j = 0; j < dim; j ++ )
                {
                        int ai, aj;

                        ai = 0;
                        aj = 0;

                        for ( k = 0; k < dim; k ++ )
                        {
                                if ( k == j )
                                        continue;
                                else
                                {
                                for ( l = 0; l < dim; l ++ )
                                {
                                        if ( l != i )
                                        {
                                                A[ai][aj] = ma[k][l];
                                                aj ++;
                                        }
                                        else
                                                continue;
                                }

                                ai ++;
                                aj = 0;
                        }
                }

                det_B = determ( dim - 1, A );
                if ( n != Right_Numb - 1 )
                        det_B = det_B + ( random ( 20 ) - 10 );

                mtr[i][j] = drobi ( pow( -1, i + j ) * det_B, det_A );
                mtr[i][j].sokrat();
                }

                sprintf( buf, "pow(A,-1)=!(Matrix(%d,%d", dim, dim );

                for ( i = 0; i < dim; i ++ )
                for ( j = 0; j < dim; j ++ )
                {
                        sprintf( buf1, ",%s", DrobiToStr( mtr[i][j] ) );
                        strcat( buf, buf1 );
                }

                strcat( buf, "))" );
                plist->Add( strdup(buf) );
        }

        /*sprintf(buf,"String(@Часть преподавателя )");
        plist->Add(strdup(buf));

        sprintf(buf,"String(\"Тема - %s \")",selecttask->name);
        plist->Add(strdup(buf));

        sprintf(buf,"String(ВАРИАНТ   %i, решение задачи %i, ключ %i)",nvar,nzad,keygen);
        plist->Add(strdup(buf));

        sprintf(buf,"String( Правильный ответ - %c)", 'a' + Right_Numb - 1 );
        plist->Add(strdup(buf));
        GenHtml->Right_Number = Right_Numb;*/

        t.pr_tst = 1;
        t.ch_ask = 5;
        t.right_ask = Right_Numb;
        t.msg = "Тест успешно сгенерирован.";

        keygen = 0;

        delete buf;
        delete buf1;

        return 0;
}