vec3n.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // Big Vector and Sparse Matrix Classes
  3. //
  4. #include <float.h>
  5. #include "vec3n.h"
  6. float conjgrad_lasterror;
  7. float conjgrad_epsilon = 0.1f;
  8. int conjgrad_loopcount;
  9. int conjgrad_looplimit = 100;
  10. /*EXPORTVAR(conjgrad_lasterror);
  11. EXPORTVAR(conjgrad_epsilon );
  12. EXPORTVAR(conjgrad_loopcount);
  13. EXPORTVAR(conjgrad_looplimit);
  14. */
  15. int ConjGradient(float3N &X, float3Nx3N &A, float3N &B)
  16. {
  17. // Solves for unknown X in equation AX=B
  18. conjgrad_loopcount=0;
  19. int n=B.count;
  20. float3N q(n),d(n),tmp(n),r(n);
  21. r = B - Mul(tmp,A,X); // just use B if X known to be zero
  22. d = r;
  23. float s = dot(r,r);
  24. float starget = s * squared(conjgrad_epsilon);
  25. while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
  26. {
  27. Mul(q,A,d); // q = A*d;
  28. float a = s/dot(d,q);
  29. X = X + d*a;
  30. if(conjgrad_loopcount%50==0)
  31. {
  32. r = B - Mul(tmp,A,X);
  33. }
  34. else
  35. {
  36. r = r - q*a;
  37. }
  38. float s_prev = s;
  39. s = dot(r,r);
  40. d = r+d*(s/s_prev);
  41. }
  42. conjgrad_lasterror = s;
  43. return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
  44. }
  45. int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B,int3 hack)
  46. {
  47. // obsolete!!!
  48. // Solves for unknown X in equation AX=B
  49. conjgrad_loopcount=0;
  50. int n=B.count;
  51. float3N q(n),d(n),tmp(n),r(n);
  52. r = B - Mul(tmp,A,X); // just use B if X known to be zero
  53. r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
  54. d = r;
  55. float s = dot(r,r);
  56. float starget = s * squared(conjgrad_epsilon);
  57. while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
  58. {
  59. Mul(q,A,d); // q = A*d;
  60. q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0,0,0);
  61. float a = s/dot(d,q);
  62. X = X + d*a;
  63. if(conjgrad_loopcount%50==0)
  64. {
  65. r = B - Mul(tmp,A,X);
  66. r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0);
  67. }
  68. else
  69. {
  70. r = r - q*a;
  71. }
  72. float s_prev = s;
  73. s = dot(r,r);
  74. d = r+d*(s/s_prev);
  75. d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0,0,0);
  76. }
  77. conjgrad_lasterror = s;
  78. return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
  79. }
  80. static inline void filter(float3N &V,const float3Nx3N &S)
  81. {
  82. for(int i=0;i<S.blocks.count;i++)
  83. {
  84. V[S.blocks[i].r] = V[S.blocks[i].r]*S.blocks[i].m;
  85. }
  86. }
  87. int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S)
  88. {
  89. // Solves for unknown X in equation AX=B
  90. conjgrad_loopcount=0;
  91. int n=B.count;
  92. float3N q(n),d(n),tmp(n),r(n);
  93. r = B - Mul(tmp,A,X); // just use B if X known to be zero
  94. filter(r,S);
  95. d = r;
  96. float s = dot(r,r);
  97. float starget = s * squared(conjgrad_epsilon);
  98. while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit)
  99. {
  100. Mul(q,A,d); // q = A*d;
  101. filter(q,S);
  102. float a = s/dot(d,q);
  103. X = X + d*a;
  104. if(conjgrad_loopcount%50==0)
  105. {
  106. r = B - Mul(tmp,A,X);
  107. filter(r,S);
  108. }
  109. else
  110. {
  111. r = r - q*a;
  112. }
  113. float s_prev = s;
  114. s = dot(r,r);
  115. d = r+d*(s/s_prev);
  116. filter(d,S);
  117. }
  118. conjgrad_lasterror = s;
  119. return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
  120. }
  121. // test big vector math library:
  122. static void testfloat3N()
  123. {
  124. float3N a(2),b(2),c(2);
  125. a[0] = float3(1,2,3);
  126. a[1] = float3(4,5,6);
  127. b[0] = float3(10,20,30);
  128. b[1] = float3(40,50,60);
  129. // c = a+b+b * 10.0f;
  130. // float d = dot(a+b,-b);
  131. int k;
  132. k=0;
  133. }
  134. class dotest{public:dotest(){testfloat3N();}}do_test_at_program_startup;