int iReducedRowEchelon(int *Mx, int nr, int nc, int *V, int RemoveGCD) { /* M.B. Boisen, Jr. & G.V. Gibbs Mathematical Crystallography, Revised Edition 1990 pp. 317-320 */ int pr, pc, ir, ic, piv, mir, lcm, gcd, fp, fi; #define Mx(i, j) Mx[i * nc + j] pc = 0; for (pr = 0; pr < nr; pr++, pc++) { for (; pc < nc; pc++) for (ir = pr; ir < nr; ir++) if ((piv = Mx(ir, pc)) != 0) goto DoRowOp; break; DoRowOp: if (ir != pr) { for (ic = 0; ic < nc; ic++) { fi = Mx(ir, ic); Mx(ir, ic) = Mx(pr, ic); Mx(pr, ic) = fi; } if (V) { fi = V[ir]; V[ir] = V[pr]; V[pr] = fi; } } for (ir = 0; ir < nr; ir++) { if (ir == pr) continue; if ((mir = Mx(ir, pc)) == 0) continue; lcm = iLCM(piv, mir); fp = lcm / piv; fi = lcm / mir; for (ic = 0; ic < nc; ic++) { Mx(ir, ic) *= fi; Mx(ir, ic) -= fp * Mx(pr, ic); } if (V) { V[ir] *= fi; V[ir] -= fp * V[pr]; } } } for (ir = 0; ir < pr; ir++) { if (RemoveGCD) { gcd = (V ? V[ir] : 0); for (ic = ir; ic < nc; ic++) gcd = iGCD(gcd, Mx(ir, ic)); } else gcd = 1; for (ic = ir; ic < nc; ic++) if ((fi = Mx(ir, ic)) != 0) { if (fi < 0) gcd *= -1; break; } for (; ic < nc; ic++) Mx(ir, ic) /= gcd; if (V) V[ir] /= gcd; } #undef Mx return pr; }
void cal_fun(vector<QPointF> point_v, vector<Func> &func_v) { if(point_v.size() <= 2) { func_v.clear(); return; } int n = point_v.size(); func_v.clear(); func_v.resize(n-1); vector<double> Mx(n); vector<double> My(n); vector<double> A(n-2); vector<double> B(n-2); vector<double> C(n-2); vector<double> Dx(n-2); vector<double> Dy(n-2); vector<double> h(n-1); for(int i = 0; i < n-1; i++) { h[i] = sqrt(pow(point_v[i+1].x() - point_v[i].x(), 2) + pow(point_v[i+1].y() - point_v[i].y(), 2)); } for(int i = 0; i < n-2; i++) { A[i] = h[i]; B[i] = 2*(h[i]+h[i+1]); C[i] = h[i+1]; Dx[i] = 6*( (point_v[i+2].x() - point_v[i+1].x())/h[i+1] - (point_v[i+1].x() - point_v[i].x())/h[i] ); Dy[i] = 6*( (point_v[i+2].y() - point_v[i+1].y())/h[i+1] - (point_v[i+1].y() - point_v[i].y())/h[i] ); } //TDMA C[0] = C[0] / B[0]; Dx[0] = Dx[0] / B[0]; Dy[0] = Dy[0] / B[0]; for(int i = 1; i < n-2; i++) { double tmp = B[i] - A[i]*C[i-1]; C[i] = C[i] / tmp; Dx[i] = (Dx[i] - A[i]*Dx[i-1]) / tmp; Dy[i] = (Dy[i] - A[i]*Dy[i-1]) / tmp; } Mx[n-2] = Dx[n-3]; My[n-2] = Dy[n-3]; for(int i = n-4; i >= 0; i--) { Mx[i+1] = Dx[i] - C[i]*Mx[i+2]; My[i+1] = Dy[i] - C[i]*My[i+2]; } Mx[0] = 0; Mx[n-1] = 0; My[0] = 0; My[n-1] = 0; for(int i = 0; i < n-1; i++) { func_v[i].a_x = point_v[i].x(); func_v[i].b_x = (point_v[i+1].x() - point_v[i].x())/h[i] - (2*h[i]*Mx[i] + h[i]*Mx[i+1]) / 6; func_v[i].c_x = Mx[i]/2; func_v[i].d_x = (Mx[i+1] - Mx[i]) / (6*h[i]); func_v[i].a_y = point_v[i].y(); func_v[i].b_y = (point_v[i+1].y() - point_v[i].y())/h[i] - (2*h[i]*My[i] + h[i]*My[i+1]) / 6; func_v[i].c_y = My[i]/2; func_v[i].d_y = (My[i+1] - My[i]) / (6*h[i]); func_v[i].h = h[i]; } }