Browse Source

* patch by Petr-K to fix 3*3 matrix inversion, resolves #19828
+ tests

git-svn-id: trunk@18213 -

florian 14 years ago
parent
commit
8833c1cfa3
5 changed files with 110 additions and 9 deletions
  1. 1 0
      .gitattributes
  2. 6 6
      rtl/inc/mmatimp.inc
  3. 2 2
      tests/Makefile
  4. 1 1
      tests/Makefile.fpc
  5. 100 0
      tests/test/units/matrix/tinv1.pp

+ 1 - 0
.gitattributes

@@ -10589,6 +10589,7 @@ tests/test/units/math/tmask2.pp svneol=native#text/plain
 tests/test/units/math/tnaninf.pp svneol=native#text/plain
 tests/test/units/math/tpower.pp svneol=native#text/pascal
 tests/test/units/math/ttrig1.pp svneol=native#text/plain
+tests/test/units/matrix/tinv1.pp svneol=native#text/pascal
 tests/test/units/objects/testobj.pp svneol=native#text/plain
 tests/test/units/objects/testobj1.pp svneol=native#text/plain
 tests/test/units/objects/testobj2.pp svneol=native#text/plain

+ 6 - 6
rtl/inc/mmatimp.inc

@@ -185,13 +185,13 @@ function objectname.inverse(Adeterminant:datatype):objectname;
 begin
     Adeterminant:=1/Adeterminant;
     inverse.data[0,0]:=(data[1,1]*data[2,2]-data[2,1]*data[1,2])*Adeterminant;
-    inverse.data[0,1]:=-(data[1,0]*data[2,2]-data[2,0]*data[1,2])*Adeterminant;
-    inverse.data[0,2]:=(data[1,0]*data[2,1]-data[2,0]*data[1,1])*Adeterminant;
-    inverse.data[1,0]:=-(data[0,1]*data[2,2]-data[2,1]*data[0,2])*Adeterminant;
+    inverse.data[0,1]:=-(data[0,1]*data[2,2]-data[2,1]*data[0,2])*Adeterminant;
+    inverse.data[0,2]:=(data[0,1]*data[1,2]-data[1,1]*data[0,2])*Adeterminant;
+    inverse.data[1,0]:=-(data[1,0]*data[2,2]-data[2,0]*data[1,2])*Adeterminant;
     inverse.data[1,1]:=(data[0,0]*data[2,2]-data[2,0]*data[0,2])*Adeterminant;
-    inverse.data[1,2]:=-(data[0,0]*data[2,1]-data[2,0]*data[0,1])*Adeterminant;
-    inverse.data[2,0]:=(data[0,1]*data[1,2]-data[1,1]*data[0,2])*Adeterminant;
-    inverse.data[2,1]:=-(data[0,0]*data[1,2]-data[1,0]*data[0,2])*Adeterminant;
+    inverse.data[1,2]:=-(data[0,0]*data[1,2]-data[1,0]*data[0,2])*Adeterminant;
+    inverse.data[2,0]:=(data[1,0]*data[2,1]-data[2,0]*data[1,1])*Adeterminant;
+    inverse.data[2,1]:=-(data[0,0]*data[2,1]-data[2,0]*data[0,1])*Adeterminant;
     inverse.data[2,2]:=(data[0,0]*data[1,1]-data[1,0]*data[0,1])*Adeterminant;
 end;
 {$endif}

+ 2 - 2
tests/Makefile

@@ -1,5 +1,5 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2011/08/03]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2011/08/14]
 #
 default: allexectests
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-solaris x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
@@ -1510,7 +1510,7 @@ endif
 ifndef LOG
 export LOG:=$(TEST_OUTPUTDIR)/log
 endif
-TESTSUBDIRS=cg cg/variants cg/cdecl library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils
+TESTSUBDIRS=cg cg/variants cg/cdecl library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix
 TESTPACKAGESUBDIRS=packages/win-base packages/webtbs packages/hash packages/fcl-registry packages/fcl-process packages/zlib packages/fcl-db packages/fcl-base packages/fcl-xml packages/cocoaint
 ifdef QUICKTEST
 export QUICKTEST

+ 1 - 1
tests/Makefile.fpc

@@ -131,7 +131,7 @@ endif
 
 
 # Subdirs available in the test subdir
-TESTSUBDIRS=cg cg/variants cg/cdecl library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils
+TESTSUBDIRS=cg cg/variants cg/cdecl library opt units/system units/dos units/crt units/objects units/strings units/sysutils units/math units/sharemem units/strutils units/matrix
 TESTPACKAGESUBDIRS=packages/win-base packages/webtbs packages/hash packages/fcl-registry packages/fcl-process packages/zlib packages/fcl-db packages/fcl-base packages/fcl-xml packages/cocoaint
 
 ifdef QUICKTEST

+ 100 - 0
tests/test/units/matrix/tinv1.pp

@@ -0,0 +1,100 @@
+uses
+  matrix;
+
+procedure do_error(i : longint);
+  begin
+    writeln('Error: ',i);
+    halt(1);
+  end;
+
+procedure test_matrix2_extended;
+var
+  m1,m2,m3 : tmatrix2_extended;
+  i,j : longint;
+begin
+  m1.data[0,0]:=1;
+  m1.data[0,1]:=1;
+  m1.data[1,0]:=1;
+  m1.data[1,1]:=-1;
+  m1:=m1/sqrt(2);
+  m2:=m1.inverse(m1.determinant);
+
+  m3:=m1.transpose;
+  { m1^(-1) must be equal m1^T because m1 is orthogonal }
+  for i:=0 to high(m2.data) do
+    for j:=0 to high(m2.data[0]) do
+      if abs(m2.data[i,j]-m3.data[i,j])>1e-10 then
+        begin
+          writeln(m2.data[i,j],'<>',m3.data[i,j]);
+          do_error(2002);
+        end;
+end;
+
+procedure test_matrix3_extended;
+var
+  m1,m2,m3 : tmatrix3_extended;
+  i,j : longint;
+begin
+  m1.data[0,0]:=2;
+  m1.data[0,1]:=-2;
+  m1.data[0,2]:=1;
+  m1.data[1,0]:=1;
+  m1.data[1,1]:=2;
+  m1.data[1,2]:=2;
+  m1.data[2,0]:=2;
+  m1.data[2,1]:=1;
+  m1.data[2,2]:=-2;
+  m1:=m1/3;
+  m2:=m1.inverse(m1.determinant);
+
+  m3:=m1.transpose;
+  { m1^(-1) must be equal m1^T because m1 is orthogonal }
+  for i:=0 to high(m2.data) do
+    for j:=0 to high(m2.data[0]) do
+      if abs(m2.data[i,j]-m3.data[i,j])>1e-10 then
+        begin
+          writeln(m2.data[i,j],'<>',m3.data[i,j]);
+          do_error(3002);
+        end;
+end;
+
+procedure test_matrix4_extended;
+var
+  m1,m2,m3 : tmatrix4_extended;
+  i,j : longint;
+begin
+  m1.data[0,0]:=2;
+  m1.data[0,1]:=-2;
+  m1.data[0,2]:=1;
+  m1.data[0,3]:=7;
+  m1.data[1,0]:=1;
+  m1.data[1,1]:=2;
+  m1.data[1,2]:=2;
+  m1.data[1,3]:=5;
+  m1.data[2,0]:=2;
+  m1.data[2,1]:=1;
+  m1.data[2,2]:=-2;
+  m1.data[2,3]:=-1;
+  m1.data[3,0]:=8;
+  m1.data[3,1]:=-9;
+  m1.data[3,2]:=2;
+  m1.data[3,3]:=-1;
+  m2:=m1.inverse(m1.determinant);
+
+  m3:=m1*m2;
+  for i:=0 to high(m3.data) do
+    for j:=0 to high(m3.data[0]) do
+      if (i<>j) and (abs(m3.data[i,j])>1e-10) or
+        (i=j) and (abs(m3.data[i,j]-1)>1e-10) then
+        begin
+          writeln(i,' ',j,m3.data[i,j]);
+          do_error(4002);
+        end;
+end;
+
+begin
+  test_matrix2_extended;
+  test_matrix3_extended;
+  test_matrix4_extended;
+  writeln('ok');
+end.