HP Forums

Full Version: Help Match?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm trying to enter the program below but it comes up with an error on the last line which usually means a mismatched begin...end; or if...end; or something similar. I've checked it until my eyes are blue in the face (how's that for a mixed metaphor?) and I can't see any problem. Is there someone willing to give it a look and let us know where I went wrong? Thanks!

Code:
EP := 1e-15;                 // approximate zero

export conic()
begin
    local t;
    makemat (r,6); makemat (c,6);

    //             A   B   C    D    E   F
    set_conic( c, 14, -4, 11, -44, -58, 71 );
    put_conic( c );
    t := conic_type( c );
    if t <> 0 then 
        standard_conic( r, c, t );
        put_conic( r );
    end;

end;

// set values of conic coefficient array
set_conic( coef, a, b, c, d, ee, f )
begin

    coef(1) := a;
    coef(2) := b;
    coef(3) := c;
    coef(4) := d;
    coef(5) := ee;
    coef(6) := f;

end;

// determines the type of conic section and returns a type code
//
//   0 - degenerate
//   1 - circle, 
//   2 - ellipse
//   3 - hyperbola
//   4 - parabola
//
conic_type( x )
begin

    local str := "conic is ";
    local t := 0;
    
    local A := x(1);
    local B := x(2);
    local C := x(3);
    local D := x(4);
    local E := x(5);
    local F := x(6);

    //       |  F   D/2  E/2 |
    //   M = | D/2   A   B/2 |
    //       | E/2  B/2   C  |

    local M11 := A*C - B*B/4;
    local M23 := D*E/4 - B*F/2; 
    local det := A*C*F + (B*D*E - B*B*F - C*D*D - A*E*E)/4; 

    if det == 0 then                     // conic is degenerate
        t := 0;
        if M11 > EP then
            str := str + "point";
        else
            if M11 < -EP then
                if A + C == 0 then
                    str := str + "two perpendicular lines";
                else
                    str := str + "two intersecting lines";
                end;
            else
                if M23 == 0 then
                    str := str + "a single line";
                else
                    str := str + "two parallel lines";
                end;
            end;
        end;
    else  
        if M11 > EP then               // conic is ellipse, parabola, or hyperbola
            if A*det > 0 then           // no solution
                t := 0;
                str := str + "nothing";
            else 
                if (A == C) and (B == 0) then
                    str := str + "a circle";
                    t := 1;
                else
                    str := str + "an ellipse";
                    t := 2;
                end;
            end;    
        else
            if M11 < -EP then
                str := str + "a hyperbola";
                t := 3;
            else
                str := str + "a parabola";
                t := 4;
            end;
        end;
    end; 
    print(str);
    return t;
    
end;

// find standard conic equation corresponding to general equation
// by removing rotation and then translation
standard_conic( r, x, t )
begin

    local A := x(1);
    local B := x(2);
    local C := x(3);
    local D := x(4);
    local E := x(5);
    local F := x(6);

    // compute rotation for coordinate frame of standard conic
    // and coefficients of rotated conic
    local theta;
    if A == C then
        theta := PI/4;
    else
        theta := 0.5*atan( B / (A - C) );
    end;

    local Sa :=  sin(theta);
    local Ca :=  cos(theta);
    local Ar :=  A*Ca*Ca + B*Sa*Ca + C*Sa*Sa;
    local Cr :=  A*Sa*Sa - B*Sa*Ca + C*Ca*Ca;
    local Dr :=  D*Ca + E*Sa;
    local Er := -D*Sa + E*Ca;
    local Fr :=  F;
    print("rotation    = "+ round((180*theta/PI),4)+ "°");

    // compute offset of coordinate frame of standard conic
    // and coefficients of translated conic
    local Xo, Yo, a2, b2, c, p;
    local i;
    
    for i := 1 to 6 do                   // init coefficients to zero
        r(i) := 0;
    end;

    if (t == 1) or (t == 2) or (t == 3) then
        // circle, ellipse, or hyperbola
        Xo := -Dr/(2*Ar);
        Yo := -Er/(2*Cr);
        print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
        r(1) := Ar/(Ar*Xo*Xo + Cr*Yo*Yo - Fr);
        r(3) := Cr/(Ar*Xo*Xo + Cr*Yo*Yo - Fr);
        r(6) := -1.0;
        if abs(r(1)) < abs(r(3)) then   // foci on x-axis
            a2 := abs(1 / r(1));
            b2 := abs(1 / r(3));
            if t == 2 then               // ellipse
                c := sqrt( a2 - b2 );
                print("foci = {±"+ round(c,4)+ ", 0.0000}");
                print("eccentricity = "+ c / sqrt(a2));
            else
                if t == 3 then            // hyperbola
                    c := sqrt( a2 + b2 );
                    print("foci = {±"+ round(c,4)+ ", 0.0000}");
                    print("eccentricity = "+ c / sqrt(a2));
                end;
            end;
        else                            // foci on y-axis
            a2 := abs(1 / r(3));
            b2 := abs(1 / r(1));
            if t == 2 then               // ellipse
                c := sqrt( a2 - b2 );
                print("foci = {0.0000, ±"+ round(c,4)+ "}");
                print("eccentricity = "+ c / sqrt(a2));
            else
                if t == 3 then            // hyperbola
                    c := sqrt( a2 + b2 );
                    print("foci = {0.0000, ±"+ round(c,4)+ "}");
                    print("eccentricity = "+ c / sqrt(a2));
                end;
            end;
        end;
    else
        if t == 4 then                    // parabola
            if abs(Ar) > abs(Cr) then    // form: x² - 4·p·y = 0
                Xo := Dr/(2*Ar);
                Yo := (Fr - Dr*Dr/(4*Ar))/Er;
                print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
                r(1) := 1;
                r(5) := Er / Ar;
                p := -r(5)/4;
                print("focus = {0, "+ round(p,4)+ "}");
            end; 
        else                            // form: y² - 4·p·x = 0
            Xo := (Fr - Er*Er/(4*Cr))/Dr;
            Yo := Er/(2*Cr);
            print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
            r(3) := 1;
            r(4) := Dr / Cr;
            p := -r(4)/4;
            print("focus = {"+ round(p,4)+ ", 0}");
        end;
    end;    
   
end;

// display a general conic equation
put_conic( x )
begin

    local i;
    local s := false;
    temp := "";

    for i := 1 to 6 do

        if x(i)==0 then
            continue
        end;

        if x(i) < 0 then
            temp := temp + " - ";
        else
            if (i > 1) and s <> 0 then
                temp := temp +" + ";
            end;
        end;

        s := true;

        if (abs(x(i)) <> 1) or (i == 6) then
            temp := temp + round(abs(x(i)),4);
            if i <> 6 then
                temp := temp + "·";
            end;
        end;

        case
        if i == 1 then temp := temp + "x²"  end;
        if i == 2 then temp := temp + "x·y" end;
        if i == 3 then temp := temp + "y²"  end;
        if i == 4 then temp := temp + "x"   end;
        if i == 5 then temp := temp + "y"   end;
        end;

    end;

    print(temp + " = 0");

end;
Three mistakes i found are:

line 220 should have a semicolon after continue
line 215 temp variable isn't defined
line 6, variables c and r are not defined

-road
(12-01-2022 02:11 AM)roadrunner Wrote: [ -> ]Three mistakes i found are:

line 220 should have a semicolon after continue
line 215 temp variable isn't defined
line 6, variables c and r are not defined

-road

Thanks! I still had problems because all function parameters are passed by value rather than reference but by making the arrays global, I bypassed that problem.

Code:
EP := 1e-15;                 // approximate zero
coef := makemat(0,6);
r := makemat(0,6);

export conic()
begin
    local t;

    //          A   B   C    D   EE   F
    set_conic( 14, -4, 11, -44, -58, 71 );
    put_conic( coef );
    t := conic_type( coef );
    if t <> 0 then 
        standard_conic( coef, t );
        put_conic( r );
    end;

end;

// set values of conic coefficient array
set_conic( a, b, c, d, ee, f )
begin
 
    coef(1) := a;
    coef(2) := b;
    coef(3) := c;
    coef(4) := d;
    coef(5) := ee;
    coef(6) := f;

end;

// determines the type of conic section and returns a type code
//
//   0 - degenerate
//   1 - circle, 
//   2 - ellipse
//   3 - hyperbola
//   4 - parabola
//
conic_type( x )
begin

    local str := "conic is ";
    local t := 0;
    
    local A := x(1);
    local B := x(2);
    local C := x(3);
    local D := x(4);
    local E := x(5);
    local F := x(6);

    //       |  F   D/2  E/2 |
    //   M = | D/2   A   B/2 |
    //       | E/2  B/2   C  |

    local M11 := A*C - B*B/4;
    local M23 := D*E/4 - B*F/2; 
    local det := A*C*F + (B*D*E - B*B*F - C*D*D - A*E*E)/4; 

    if det == 0 then                     // conic is degenerate
        t := 0;
        if M11 > EP then
            str := str + "point";
        else
            if M11 < -EP then
                if A + C == 0 then
                    str := str + "two perpendicular lines";
                else
                    str := str + "two intersecting lines";
                end;
            else
                if M23 == 0 then
                    str := str + "a single line";
                else
                    str := str + "two parallel lines";
                end;
            end;
        end;
    else  
        if M11 > EP then               // conic is ellipse, parabola, or hyperbola
            if A*det > 0 then           // no solution
                t := 0;
                str := str + "nothing";
            else 
                if (A == C) and (B == 0) then
                    str := str + "a circle";
                    t := 1;
                else
                    str := str + "an ellipse";
                    t := 2;
                end;
            end;    
        else
            if M11 < -EP then
                str := str + "a hyperbola";
                t := 3;
            else
                str := str + "a parabola";
                t := 4;
            end;
        end;
    end; 
    print(str);
    return t;
    
end;

// find standard conic equation corresponding to general equation
// by removing rotation and then translation
standard_conic( x, t )
begin

    local A := x(1);
    local B := x(2);
    local C := x(3);
    local D := x(4);
    local E := x(5);
    local F := x(6);

    // compute rotation for coordinate frame of standard conic
    // and coefficients of rotated conic
    local theta;
    if A == C then
        theta := PI/4;
    else
        theta := 0.5*atan( B / (A - C) );
    end;

    local Sa :=  sin(theta);
    local Ca :=  cos(theta);
    local Ar :=  A*Ca*Ca + B*Sa*Ca + C*Sa*Sa;
    local Cr :=  A*Sa*Sa - B*Sa*Ca + C*Ca*Ca;
    local Dr :=  D*Ca + E*Sa;
    local Er := -D*Sa + E*Ca;
    local Fr :=  F;
    print("rotation    = "+ round((180*theta/PI),4)+ "°");

    // compute offset of coordinate frame of standard conic
    // and coefficients of translated conic
    local Xo, Yo, a2, b2, c, p;
    local i;
    
    for i := 1 to 6 do                   // init coefficients to zero
        r(i) := 0;
    end;

    if (t == 1) or (t == 2) or (t == 3) then
        // circle, ellipse, or hyperbola
        Xo := -Dr/(2*Ar);
        Yo := -Er/(2*Cr);
        print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
        r(1) := Ar/(Ar*Xo*Xo + Cr*Yo*Yo - Fr);
        r(3) := Cr/(Ar*Xo*Xo + Cr*Yo*Yo - Fr);
        r(6) := -1.0;
        if abs(r(1)) < abs(r(3)) then   // foci on x-axis
            a2 := abs(1 / r(1));
            b2 := abs(1 / r(3));
            if t == 2 then               // ellipse
                c := sqrt( a2 - b2 );
                print("foci = {±"+ round(c,4)+ ", 0.0000}");
                print("eccentricity = "+ c / sqrt(a2));
            else
                if t == 3 then            // hyperbola
                    c := sqrt( a2 + b2 );
                    print("foci = {±"+ round(c,4)+ ", 0.0000}");
                    print("eccentricity = "+ c / sqrt(a2));
                end;
            end;
        else                            // foci on y-axis
            a2 := abs(1 / r(3));
            b2 := abs(1 / r(1));
            if t == 2 then               // ellipse
                c := sqrt( a2 - b2 );
                print("foci = {0.0000, ±"+ round(c,4)+ "}");
                print("eccentricity = "+ c / sqrt(a2));
            else
                if t == 3 then            // hyperbola
                    c := sqrt( a2 + b2 );
                    print("foci = {0.0000, ±"+ round(c,4)+ "}");
                    print("eccentricity = "+ c / sqrt(a2));
                end;
            end;
        end;
    else
        if t == 4 then                    // parabola
            if abs(Ar) > abs(Cr) then    // form: x² - 4·p·y = 0
                Xo := Dr/(2*Ar);
                Yo := (Fr - Dr*Dr/(4*Ar))/Er;
                print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
                r(1) := 1;
                r(5) := Er / Ar;
                p := -r(5)/4;
                print("focus = {0, "+ round(p,4)+ "}");
            end; 
        else                            // form: y² - 4·p·x = 0
            Xo := (Fr - Er*Er/(4*Cr))/Dr;
            Yo := Er/(2*Cr);
            print("translation = {"+ round(Xo,4)+ ", "+ round(Yo,4)+ "}");
            r(3) := 1;
            r(4) := Dr / Cr;
            p := -r(4)/4;
            print("focus = {"+ round(p,4)+ ", 0}");
        end;
    end;    
   
end;

// display a general conic equation
put_conic( x )
begin

    local i;
    local s := false;
    local temp := "";

    for i := 1 to 6 do

        if x(i)==0 then
            continue;
        end;

        if x(i) < 0 then
            temp := temp + " - ";
        else
            if (i > 1) and s <> 0 then
                temp := temp +" + ";
            end;
        end;

        s := true;

        if (abs(x(i)) <> 1) or (i == 6) then
            temp := temp + round(abs(x(i)),4);
            if i <> 6 then
                temp := temp + "·";
            end;
        end;

        case
        if i == 1 then temp := temp + "x²"  end;
        if i == 2 then temp := temp + "x·y" end;
        if i == 3 then temp := temp + "y²"  end;
        if i == 4 then temp := temp + "x"   end;
        if i == 5 then temp := temp + "y"   end;
        end;

    end;

    print(temp + " = 0");

end;
Reference URL's