modula3 / cm3

Critical Mass Modula-3
http://modula3.github.io/cm3/
Other
139 stars 25 forks source link

How to use Sqrt? #1076

Closed ghost closed 2 years ago

ghost commented 2 years ago

I want to return the square root of a real value. From the interface index I know about the RealSqrt interface and I put it to IMPORT. But when I use it with RealSqrt(2.0), compilation failed with unable to find interface (RealSqrt).

ghost commented 2 years ago

From the doc it seems interface sqrt is included as part of libm3. So I go to libm3 directory and I found no sqrt.i3 or sqrt.ig. The only thing I found is the sqrt directory with FloatExtras.ig and FloatExtras.mg. I opened them I found no mentioned of anything related to Sqrt at all!

ghost commented 2 years ago

Modula 2 doesn't get in the way of me like this. Everything is straight forward.

jpgpng commented 2 years ago

Modula 2 doesn't get in the way of me like this. Everything is straight forward.

Modula 2 is more like C. There is no OOP at all so one doesn't have to do with any OOP stuffs (this case is generic interfaces). Modula 2 also has no built-in build system like quake so it's definitely simpler and straight forward.

RodneyBates commented 2 years ago

I think you are mixing up interface names and names of procedures (& other things) declared within an interface.

You wrote Math.sqrt in an earlier post.  Math is the name of the interface, found in file Math.i3, specifically, m3-libs/libm3/src/arith/WIN32/Math.i3 or m3-libs/libm3/src/arith/POSIX/Math.i3. sqrt is a procedure declared inside of each version of Math.i3

On 9/10/22 13:23, pwd96m4a wrote:

From the doc it seems interface sqrt is included as part of libm3. So I go to libm3 directory and I found no sqrt.i3 or sqrt.ig. The only thing I found is the sqrt directory with FloatExtras.ig and FloatExtras.mg. I opened them I found no mentioned of anything related to Sqrt at all!

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1076#issuecomment-1242781945, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNHRV5P7TOBKVYVRPEDV5TG2DANCNFSM6AAAAAAQJK22PE. You are receiving this because you are subscribed to this thread.Message ID: @.***>

ghost commented 2 years ago

I think you are mixing up interface names and names of procedures (& other things) declared within an interface. You wrote Math.sqrt in an earlier post.  Math is the name of the interface, found in file Math.i3, specifically, m3-libs/libm3/src/arith/WIN32/Math.i3 or m3-libs/libm3/src/arith/POSIX/Math.i3. sqrt is a procedure declared inside of each version of Math.i3 On 9/10/22 13:23, pwd96m4a wrote: From the doc it seems interface sqrt is included as part of libm3. So I go to libm3 directory and I found no sqrt.i3 or sqrt.ig. The only thing I found is the sqrt directory with FloatExtras.ig and FloatExtras.mg. I opened them I found no mentioned of anything related to Sqrt at all! — Reply to this email directly, view it on GitHub <#1076 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNHRV5P7TOBKVYVRPEDV5TG2DANCNFSM6AAAAAAQJK22PE. You are receiving this because you are subscribed to this thread.Message ID: @.***>

No. After failed with this I tried to call C's math functions instead, still failed.

ghost commented 2 years ago

@RodneyBates Just show me how to return the square root of a real number (or longreal if you want). Better using the native M3 functions (this Sqrt and RealSqrt interface). But if having to resort to C functions then it's also OK.

ghost commented 2 years ago

So, the stupid interfaces don't work. Finally I found an example on the internet. This language must be very unpopular. Finding an example for it is too difficult. Finding M2 example is much easier. The key is, for Math you have to use LONGREAL (not just REAL like this RealSqrt interface). And with LONGREAL you have to append D0 to the number! This is totally optional in other languages but I have no idea why you took it so harsh this way. BTW, I have read the language definition many times, there is nowhere D0 is mentioned. The C language despite all of the bad of it, has a better document: https://en.cppreference.com/w/cpp/language/floating_literal

RodneyBates commented 2 years ago

On 9/10/22 20:28, pwd96m4a wrote:

So, the stupid interfaces don't work. Finally I found an example on the internet. This language must be very unpopular. Finding an example for it is too difficult. Finding M2 example is much easier. The key is, for Math you have to use LONGREAL (not just REAL like this RealSqrt interface). And with LONGREAL you have to append |D0| to the number! This is totally optional in other languages but I have no idea why you took it so harsh this way. BTW, I have read the language definition many times, there is nowhere |D0| is mentioned.

Modula-3 language definition, 2.6.4, Numeric Literals, 4th paragraph:

"LONGREAL and EXTENDED literals are like REAL literals, but instead of E  they use D and X respectively."

Paragraph 3 describes the common characteristics.

Also see 2.8.12 for formal syntax.

The C language despite all of the bad of it, has a better document: https://en.cppreference.com/w/cpp/language/floating_literal

— Reply to this email directly, view it on GitHub https://github.com/modula3/cm3/issues/1076#issuecomment-1242837204, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSVZNDMMMAIXUYGS35T7XTV5UYVDANCNFSM6AAAAAAQJK22PE. You are receiving this because you were mentioned.Message ID: @.***>

VictorMiasnikov commented 2 years ago

So, the stupid interfaces don't work. Finally I found an example on the internet. This language must be very unpopular. Finding an example for it is too difficult. Finding M2 example is much easier. The key is, for Math you have to use LONGREAL (not just REAL like this RealSqrt interface). And with LONGREAL you have to append D0 to the number! This is totally optional in other languages but I have no idea why you took it so harsh this way. BTW, I have read the language definition many times, there is nowhere D0 is mentioned. The C language despite all of the bad of it, has a better document: https://en.cppreference.com/w/cpp/language/floating_literal

} This is totally optional in other languages

This is use in C language for integer constants.

} ( . . .) found an example on the internet.

Be simple -). Please, see:

m3-libs\arithmetic\test\src\TestComplex.m3

MODULE TestComplex EXPORTS Test;
(* Arithmetic for Modula-3, see doc for details

   Abstract: Test driver for Complex

   1/27/96 Harry George Initial version *)

IMPORT Fmt,
       LongRealComplex       AS C,
       LongRealComplexTrans  AS CT,
       LongRealComplexFmtLex AS CF,
       LongRealPolar         AS P,
       LongRealPolarFmtLex   AS PF;

. . .

    Msg("sqrt(a)=" & CF.Fmt(CT.SqRt(a)) & "\n");
VictorMiasnikov commented 2 years ago

Or:

m3-libs\arithmetic\src\algebra\root\RootApproximation.mg

GENERIC MODULE RootApproximation(R, RT, RRt, C, CT, CP, CRt);
(* Arithmetic for Modula-3, see doc for details *)

FROM Arithmetic IMPORT Error;

(**
IMPORT LongRealComplexVectorFmtLex AS VF,
       LongRealComplexFmtLex AS CF,
       LongRealFmtLex AS RF,
       IO;
**)

<* UNUSED *>
CONST
  Module = "RootApproximation.";

(* Quadratics *)

PROCEDURE RealQuadratic (READONLY x: RealPolynomial2; ): RootArray2 =
  (* Given a*t^2+b*t+c=0, solve for t. *)
  VAR
    a                    := x[2];
    b                    := x[1];
    c                    := x[0];
    disc, q, q1, q2: R.T;
  BEGIN
    disc := b * b - FLOAT(4.0, R.T) * a * c;
    IF disc <= R.Zero THEN
      q1 := -b / a * RT.Half;
      q2 := RT.SqRt(-disc) / a * RT.Half;
      RETURN RootArray2{C.T{re := q1, im := q2}, C.T{re := q1, im := -q2}};
    ELSE
      (* avoid cancelation *)
      IF b < R.Zero THEN
        q := RT.Half * (-b + RT.SqRt(disc));
      ELSE
        q := RT.Half * (-b - RT.SqRt(disc));
      END;
      (* fails because Sgn(0)=0 :
         q:=-RT.Half*(b+RT.Sgn(b)*RT.SqRt(disc)); *)
      q1 := q / a;
      q2 := c / q;
      RETURN RootArray2{
               C.T{re := q1, im := R.Zero}, C.T{re := q2, im := R.Zero}};
    END;
  END RealQuadratic;

PROCEDURE ComplexQuadratic (READONLY x: ComplexPolynomial2; ): RootArray2
  RAISES {Error} =
  (* Given a*t^2+b*t+c=0, solve for t. *)
  CONST c4 = FLOAT(4.0, R.T);
  VAR
    a                       := x[2];
    b                       := x[1];
    c                       := x[0];
    disc, disc_sqrt, q: C.T;
  BEGIN
    disc := C.Sub(C.Mul(b, b), C.Scale(C.Mul(a, c), c4));
    disc_sqrt := CT.SqRt(disc);

    (*---set sign of sqrt via NR92 eqn 5.6.6---*)
    IF C.Mul(C.Conj(b), disc_sqrt).re > R.Zero THEN
      disc_sqrt := C.Neg(disc_sqrt);
    END;

    (*---calculate per NR92 eqn 5.6.4, 5.6.5.---*)
    q := C.Scale(C.Sub(disc_sqrt, b), RT.Half);
    RETURN RootArray2{C.Div(q, a), C.Div(c, q)};
  END ComplexQuadratic;
VictorMiasnikov commented 2 years ago

So, the stupid interfaces don't work. Finally I found an example on the internet. This language must be very unpopular. Finding an example for it is too difficult. Finding M2 example is much easier. The key is, for Math you have to use LONGREAL (not just REAL like this RealSqrt interface). And with LONGREAL you have to append D0 to the number! This is totally optional in other languages but I have no idea why you took it so harsh this way. BTW, I have read the language definition many times, there is nowhere D0 is mentioned. The C language despite all of the bad of it, has a better document: https://en.cppreference.com/w/cpp/language/floating_literal

} And with LONGREAL you have to append D0 to the number!

Please see near: FLOAT(4.0, R.T) , as example

VictorMiasnikov commented 2 years ago

P.S.

Modula 2 doesn't get in the way of me like this. Everything is straight forward.

I am not sure that M2 allow write "in this style" without memory leaks:

PROCEDURE RealNewtonMaehli (x: RRt.T; ): REF CRt.RootArray RAISES {Error} =
  VAR xc := NEW(CRt.T, NUMBER(x^));
  BEGIN
    FOR j := 0 TO LAST(xc^) DO xc[j] := C.T{x[j], R.Zero}; END;
    RETURN ComplexNewtonMaehli(xc);
  END RealNewtonMaehli;