Skip to main content
5 of 5
refine references section
138 Aspen
  • 469
  • 2
  • 8

Mathematica implementation of Welch method for constructing Costas arrays

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).

138 Aspen
  • 469
  • 2
  • 8