# Unexpected behavior of CoefficientArrays

Posted 3 months ago
699 Views
|
4 Replies
|
3 Total Likes
|
 See my following example: In[778]:= gen="-y,-z,-x"; toCA[gen_]:=Module[{g,x,y,z}, g="{"<> gen <> "}"//ToExpression; CoefficientArrays[g,{x,y,z}]//Normal ] toCA[gen] "{"<> gen <> "}"//ToExpression; CoefficientArrays[%,{x,y,z}]//Normal Out[780]= {{-y, -z, -x}} Out[782]= {{0, 0, 0}, {{0, -1, 0}, {0, 0, -1}, {-1, 0, 0}}} Why does the same code return an incorrect result after being written as a function?Regards, Zhao
4 Replies
Sort By:
Posted 3 months ago
 Use Block instead of Module
Posted 3 months ago
 Thank you for pointing out this subtle difference. I tried the following method, but still failed.In my situation, there are two wl script files opened in Mathematica. In one file, I created the following two functions and evaluated them: toRep//ClearAll; toRep[gen_?StringQ]:=Block[{coef,x,y,z}, coef=CoefficientArrays[gen,{x,y,z}]//Normal; AffineTransform[{coef[[2]],coef[[1]]}]//TransformationMatrix ] toReps//ClearAll; toReps[gens_?StringQ]:=Block[{s,x,y,z}, s=StringSplit[gens,"\n"]; toRep/@("{"<>#<>"}"&/@s//ToExpression) ] Then in another wl file, I evaluated the following code snippet: In[42]:= (* The Space Group has been identified as (No. ) Input generators -y, -z, -x y, -x, -z 1/8 + x, 1/8 + y, 1/8 + z Transformation Matrix to the standard/default setting ( ) *) SGGenSetWrongXYZ="-y,-z,-x y,-x,-z x+1/8,1/8+ y,z+1/8"; (*StringSplit[SGGenSetWrongXYZ,"\n"]; SGGenSetWrong=toRep/@("{"<>#<>"}"&/@%//ToExpression);*) toReps[SGGenSetWrongXYZ] Out[43]= {toRep[{-y, -z, -x}], toRep[{y, -x, -z}], toRep[{1/8 + x, 1/8 + y, 1/8 + z}]} As you can see, a portion of the result still appears as unevaluated.Regards, Zhao
Posted 3 months ago
 If you end up with a particular expression being unevaluated, it probably means that none of the DownValues matched the expression. So, you should start looking for pattern mismatches for toRep. You defined toRep as toRep[gen_?StringQ] (which could have just been toRep[gen_String], by the way), so one hypothesis is that what was passed to toRep wasn't a string. Indeed, if you look at the FullForm of your result, you'll see that the arguments the toRep expressions are not strings. Here is the suspicious code: toRep /@ ("{" <> # <> "}" & /@ s // ToExpression) Analyze the order of operations here, and you'll find your problem.(I'm not really sure what your strategy is here, but I'm guessing you didn't want to restrict toRep to strings.)
Posted 3 months ago
 Thank you for your comments. Changing to the following version solves this problem: toRep//ClearAll; toRep[gen_List]:=Block[{coef,x,y,z}, coef=CoefficientArrays[gen,{x,y,z}]//Normal; AffineTransform[{coef[[2]],coef[[1]]}]//TransformationMatrix ] toReps//ClearAll; toReps[gens_String]:=Block[{s,x,y,z}, s=StringSplit[gens,"\n"]; toRep/@("{"<>#<>"}"&/@s//ToExpression) ]  (I'm not really sure what your strategy is here, but I'm guessing you didn't want to restrict toRep to strings.) Yes. The reason for this problem is that I started with the toRep function at the beginning, and then I extended to call it by other functions. However, I ignored the adjustment of corresponding parameter types. When a problem like this happens, I tend not to think that it is caused by a problem in a function that has already been debugged thoroughly without problems.