2
\$\begingroup\$

I ported C++ implementation of Welch method for constructing Costas arrays to Mathematica.

Any feedback would be appreciated.

(* Welch method for generating Costas arrays *)

On["Assert"];

(* Find all primitive roots of a prime p *)
primitiveRoots[p_] := Module[{roots = {}},
  Do[
    If[MultiplicativeOrder[g, p] == p - 1, 
     AppendTo[roots, g]], 
    {g, 2, p - 1}];
  roots
]


(* Costas array verification function *)
(* Checks if a permutation is a valid Costas array using triangular difference table *)
isCostasArray[perm_] := Module[{n, diffTable, allDistinct},
  n = Length[perm];
  If[n <= 1, Return[True]]; (* trivial cases *)
  
  (* Generate triangular difference table *)
  diffTable = Table[
    Table[perm[[i + k]] - perm[[i]], {i, 1, n - k}],
    {k, 1, n - 1}
  ];
  
  (* Check if each row has distinct elements *)
  allDistinct = And @@ (DuplicateFreeQ[#] & /@ diffTable);
  
  (* Print difference table for debugging *)
  (*Print["Triangular difference table for ", perm, ":"];*)
  Do[
    Print["Row ", k, ": ", diffTable[[k]]] ,
    {k, 1, Length[diffTable]}
  ];
  Print["All rows have distinct elements: ", allDistinct];
  Print[""];
  
  allDistinct
]





(* Main computation *)
p = 13; (* Hard-coded prime *)

(* Verify p is prime *)
If[!PrimeQ[p] || p <= 2,
  Print[p, " is not a prime number greater than 2."];
  Abort[];
]

Print[p, " is a prime number."];

(* Find primitive roots *)
primitiveRootsList = primitiveRoots[p];
numPrimitiveRoots = Length[primitiveRootsList];

Print["Primitive roots:"];
Do[
  Print["Primitive root[", i - 1, "] = ", primitiveRootsList[[i]]],
  {i, 1, numPrimitiveRoots}
];

(* Generate Costas arrays *)
costasArrays = Table[
  Table[PowerMod[primitiveRootsList[[k]], j - 1, p], {j, 1, p - 1}],
  {k, 1, numPrimitiveRoots}
];

(* Print (p-1)th order Costas arrays *)
Print["(p-1)=", p - 1, "'th order Costas array:"];
Do[
  Print[costasArrays[[k]]],
  {k, 1, numPrimitiveRoots}
];

(* Generate (p-2)th order Costas arrays *)
(* Remove first element and subtract 1 from remaining elements *)
costas2Arrays = Table[
  Map[# - 1 &, Rest[costasArrays[[k]]]],
  {k, 1, numPrimitiveRoots}
];

Print["(p-2)=", p - 2, "'th order Costas array:"];
Do[
  Print[costas2Arrays[[k]]],
  {k, 1, numPrimitiveRoots}
];

(* Generate (p-3)th order Costas array if condition is met *)
(* Check if 2 is at position 2 in the first Costas array *)
If[Length[costasArrays] > 0 && Length[costasArrays[[1]]] > 1 && 
   costasArrays[[1]][[2]] == 2 && p > 3,
  (* Remove first two elements and subtract 2 from remaining *)
  costas3Array = Map[# - 2 &, Drop[costasArrays[[1]], 2]];
  Print["(p-3)=", p - 3, "'th order Costas array:"];
  Print[costas3Array];,
  (* Else *)
  Print["(p-3)'th order Costas array cannot be constructed."];
];











(* Verify that generated arrays are indeed Costas arrays *)
Print["\n=== VERIFICATION ==="];
Print["Verifying (p-1)th order Costas arrays:"];
Do[
  (*Print["Checking array ", k, ": ", costasArrays[[k]]];*)
  isValid = isCostasArray[costasArrays[[k]]];
  Print["Is valid Costas array: ", isValid];
  Print[""]; 
  Assert[isValid],
  {k, 1, numPrimitiveRoots}
];

Print["Verifying (p-2)th order Costas arrays:"];
Do[
  Print["Checking array ", k, ": ", costas2Arrays[[k]]];
  isValid = isCostasArray[costas2Arrays[[k]]];
  Print["Is valid Costas array: ", isValid];
  Print[""],
  {k, 1, numPrimitiveRoots}
];

(* Verify (p-3)th order array if it exists *)
If[Length[costasArrays] > 0 && Length[costasArrays[[1]]] > 1 && 
   costasArrays[[1]][[2]] == 2 && p > 3,
  costas3Array = Map[# - 2 &, Drop[costasArrays[[1]], 2]];
  Print["Verifying (p-3)th order Costas array:"];
  Print["Checking array: ", costas3Array];
  isValid = isCostasArray[costas3Array];
  (*Print["Is valid Costas array: ", isValid];
  Print[""];*)
  Assert[isValid];
];

(* Test with the example from the problem description *)
Print["=== EXAMPLE VERIFICATION ==="];
exampleArray = {1, 3, 4, 2, 5};
Print["Testing example array: ", exampleArray];
isCostasArray[exampleArray];

(* Display additional information *)
Print["\n=== SUMMARY ==="];
Print["Prime p = ", p];
Print["Number of primitive roots = ", numPrimitiveRoots];
Print["φ(p-1) = φ(", p - 1, ") = ", EulerPhi[p - 1]];
Print["Primitive roots: ", primitiveRootsList];

References

[1] J. H. van Lint and R. M. Wilson, "Latin squares which contain no repeated digrams," SIAM J. Appl. Math., vol. 35, no. 3, pp. 494–499, Nov. 1978, doi: 10.1137/1007035. [Online]. Available: https://www.sci-hub.ru/10.1137/1007035

[2] S. W. Golomb and H. Taylor, "Constructions and properties of Costas arrays," Proc. IEEE, vol. 72, no. 9, pp. 1143–1163, Sep. 1984, doi: 10.1109/PROC.1984.12994. [Online]. Available: https://ieeexplore.ieee.org/document/1457262

[3] A. Ardalani, "Contributions to the theory of Costas arrays," Ph.D. dissertation, Martin-Luther-Universität Halle-Wittenberg, Halle, Germany, 2023. [Online]. Available: https://opendata.uni-halle.de/bitstream/1981185920/110843/1/Ardalani_Ali_Dissertation_2023.pdf

[4] J. K. Beard, "A database of all known Costas arrays with 200 or fewer dots," [Online]. Available: https://web.archive.org/web/20210727010503/http://jameskbeard.com/jameskbeard/Costas_Arrays.html (accessed Jul. 3, 2025).

\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.