001package cnslab.cnsnetwork; 002import cnslab.cnsmath.*; 003import java.io.FileOutputStream; 004import java.io.ObjectOutputStream; 005import java.io.ObjectInputStream; 006import java.io.FileInputStream; 007import java.util.HashMap; 008import java.util.ArrayList; 009import java.util.Iterator; 010import java.util.Map; 011import java.util.Arrays; 012import java.util.TreeSet; 013/** 014 * A class of Utility functions. 015 * 016 * @author Yi Dong 017 */ 018public class FunUtil 019{ 020// public static double minAccuracy=1e-8; 021 public static double minAccuracy=1e-10; 022 023 /** 024 * Binary search for host id, given an array of neuron index, which are the last neuron index for that nethost 025 * 026 * @param endIndex 027 * @param num 028 * @return 029 */ 030 public static int hostId(int [] endIndex, int num) 031 { 032 int begin=0; 033 int end=endIndex.length-1; 034 int mid; 035 if(num>endIndex[end])throw new RuntimeException("hostId, neuron index "+num+" is out of range"+endIndex[end]); 036 037 while(end-begin>1) 038 { 039 mid=(begin+end)/2; 040 if(endIndex[mid]==num)return mid; 041 if(endIndex[mid]<num) 042 { 043 begin=mid; 044 } 045 if(endIndex[mid]>num) 046 { 047 end=mid; 048 } 049 } 050 return (endIndex[begin]>=num ? begin:end ); 051 } 052 /* 053 054 public static Neuron[] randomVSICLNetwork(int[] endIndex,int numSyn,int numSensory) 055 { 056 //int[] endIndex={ 1000,2000,3000,4000,5000,6000,7000,8000,9000,10000}; 057 058 int totalNum=endIndex[endIndex.length-1]+1; 059 //int numSyn=1000; 060 int numTasks=endIndex.length; 061 //int numSensory=10; 062 063 if(numSyn > totalNum) throw new RuntimeException("# of synapses are more than neurons"); 064 Seed idum= new Seed(-3); 065 066 Neuron [] neurons; 067 Synapse [] synapses; 068 Branch [] branches; 069 070 neurons = new Neuron[totalNum]; 071 072 for(int neuIndex=0; neuIndex< totalNum; neuIndex++) 073 { 074 HashMap<String, ArrayList<Synapse> > tmp_bran= new HashMap<String,ArrayList<Synapse> >(); 075 076 int number = (int)(Cnsran.ran2(idum)*numSyn); 077 078 HashMap<Integer,Boolean> nore = new HashMap<Integer, Boolean>(); 079 HashMap<String,Double> delays = new HashMap<String,Double>(); 080 081 for(int i=0; i< number ;i++) 082 { 083 int x= (int)(Cnsran.ran2(idum)*3); 084 double delay=0.002; 085 if(x==0)delay=0.002; 086 if(x==1)delay=0.003; 087 if(x==2)delay=0.004; 088 089 int targetId = (int)(Cnsran.ran2(idum)*totalNum); 090 while(targetId==neuIndex || targetId < numSensory || nore.containsKey(targetId) ) 091 { 092 targetId = (int)(Cnsran.ran2(idum)*totalNum); 093 } 094 nore.put(targetId,true); 095 096 int targetHostId=FunUtil.hostId(endIndex,targetId); 097 098 if(tmp_bran.get(delay+";"+targetHostId)==null) 099 { 100 tmp_bran.put( delay+";"+targetHostId, (new ArrayList<Synapse>())); 101 } 102 delays.put(delay+";"+targetHostId,delay); 103 104 if(neuIndex < numSensory) 105 { 106 if(Cnsran.ran2(idum)<1) 107 { 108 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, 1e-10, 0)); //excitatory 109 } 110 else 111 { 112 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, -2e-13, 1));//inhibitory 113 } 114 } 115 else 116 { 117 if(Cnsran.ran2(idum)<0.5) 118 { 119 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, 1e-10, 0)); //excitatory 120 } 121 else 122 { 123 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, -2e-11, 1));//inhibitory 124 } 125 } 126 } 127 128 Iterator< Map.Entry<String, ArrayList<Synapse> > > values = tmp_bran.entrySet().iterator(); 129 130 branches= new Branch[tmp_bran.size()]; 131 int iter=0; 132 while(values.hasNext()) 133 { 134 Map.Entry<String, ArrayList<Synapse> > entry= values.next(); 135 //System.out.println((values.next()).toArray()[0]); 136 //System.out.println((values.next()).toArray().length); 137 138 Synapse[] syns=(entry.getValue()).toArray(new Synapse [0]); 139 //Arrays.sort(syns); 140 branches[iter]= new Branch(syns, delays.get(entry.getKey())) ; 141 iter++; 142 } 143 if(neuIndex<numSensory) 144 { 145 Seed idum2= new Seed(-neuIndex); 146 neurons[neuIndex] = new BKPoissonNeuron(idum2,400.0,new Axon(branches)); // seed, background freq, axon 147 } 148 else 149 { 150 neurons[neuIndex] = new VSICLIFNeuron(-0.07,0.01,-0.05,new double[] {0.0,0.0}, new Axon(branches)); // seed, background freq, axon 151 } 152 } 153 return neurons; 154 } 155 public static Neuron[] randomNetwork(int[] endIndex,int numSyn,int numSensory) 156 { 157 //int[] endIndex={ 1000,2000,3000,4000,5000,6000,7000,8000,9000,10000}; 158 159 int totalNum=endIndex[endIndex.length-1]+1; 160 //int numSyn=1000; 161 int numTasks=endIndex.length; 162 //int numSensory=10; 163 164 if(numSyn > totalNum) throw new RuntimeException("# of synapses are more than neurons"); 165 Seed idum= new Seed(-3); 166 167 Neuron [] neurons; 168 Synapse [] synapses; 169 Branch [] branches; 170 171 neurons = new Neuron[totalNum]; 172 173 for(int neuIndex=0; neuIndex< totalNum; neuIndex++) 174 { 175 HashMap<String, ArrayList<Synapse> > tmp_bran= new HashMap<String,ArrayList<Synapse> >(); 176 177 int number = (int)(Cnsran.ran2(idum)*numSyn); 178 179 HashMap<Integer,Boolean> nore = new HashMap<Integer, Boolean>(); 180 HashMap<String,Double> delays = new HashMap<String,Double>(); 181 182 for(int i=0; i< number ;i++) 183 { 184 int x= (int)(Cnsran.ran2(idum)*3); 185 double delay=0.002; 186 if(x==0)delay=0.002; 187 if(x==1)delay=0.003; 188 if(x==2)delay=0.004; 189 190 int targetId = (int)(Cnsran.ran2(idum)*totalNum); 191 while(targetId==neuIndex || targetId < numSensory || nore.containsKey(targetId) ) 192 { 193 targetId = (int)(Cnsran.ran2(idum)*totalNum); 194 } 195 nore.put(targetId,true); 196 197 int targetHostId=FunUtil.hostId(endIndex,targetId); 198 199 if(tmp_bran.get(delay+";"+targetHostId)==null) 200 { 201 tmp_bran.put( delay+";"+targetHostId, (new ArrayList<Synapse>())); 202 } 203 delays.put(delay+";"+targetHostId,delay); 204 205 if(neuIndex < numSensory) 206 { 207 if(Cnsran.ran2(idum)<1) 208 { 209 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, 1e-10, 0)); //excitatory 210 } 211 else 212 { 213 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, -2e-13, 1));//inhibitory 214 } 215 } 216 else 217 { 218 if(Cnsran.ran2(idum)<0.5) 219 { 220 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, 1e-10, 0)); //excitatory 221 } 222 else 223 { 224 tmp_bran.get( delay+";"+targetHostId).add(new Synapse(targetId, -2e-11, 1));//inhibitory 225 } 226 } 227 228 } 229 230 Iterator< Map.Entry<String, ArrayList<Synapse> > > values = tmp_bran.entrySet().iterator(); 231 232 branches= new Branch[tmp_bran.size()]; 233 int iter=0; 234 while(values.hasNext()) 235 { 236 Map.Entry<String, ArrayList<Synapse> > entry= values.next(); 237 //System.out.println((values.next()).toArray()[0]); 238 //System.out.println((values.next()).toArray().length); 239 240 Synapse[] syns=(entry.getValue()).toArray(new Synapse [0]); 241 //Arrays.sort(syns); 242 branches[iter]= new Branch(syns, delays.get(entry.getKey())) ; 243 iter++; 244 } 245 if(neuIndex<numSensory) 246 { 247 Seed idum2= new Seed(-neuIndex); 248 neurons[neuIndex] = new BKPoissonNeuron(idum2,400.0,new Axon(branches)); // seed, background freq, axon 249 } 250 else 251 { 252 neurons[neuIndex] = new SIFNeuron(-0.07,0.01,new Axon(branches)); // seed, background freq, axon 253 } 254 } 255 return neurons; 256 } 257 */ 258 259 /** 260 * left rotate matrix 90 degree 261 * 262 * @param matrix 263 * @return mattrix array 264 */ 265 public static double[][] lRotate90(double conn [][]) 266 { 267 int m; 268 m=conn.length; 269 int n; 270 n=conn[0].length; 271 double [][] out= new double[n][m]; 272 273 for(int i=0;i<n;i++) 274 { 275 for(int j=0;j<m;j++) 276 { 277 out[i][j]=conn[j][n-i-1]; 278 } 279 } 280 return out; 281 } 282 283 /** 284 * right rotate matrix 90 degree 285 * 286 * @param matrix 287 * @return mattrix array 288 */ 289 public static double[][] rRotate90(double conn [][]) 290 { 291 int m; 292 m=conn.length; 293 int n; 294 n=conn[0].length; 295 double [][] out= new double[n][m]; 296 297 for(int i=0;i<n;i++) 298 { 299 for(int j=0;j<m;j++) 300 { 301 out[i][j]=conn[m-j-1][i]; 302 } 303 } 304 return out; 305 } 306 307 /** 308 * Compute the standard deviation of the vector 309 * 310 * @param vector 311 * @return standard deviation 312 */ 313 public static double sd(double []d) 314 { 315 return Math.sqrt(var(d)); 316 } 317 318 /** 319 * Compute the standard deviation of the vector, starting at start 320 * @param starting index 321 * @param vector 322 * @return standard deviation 323 */ 324 public static double sd(int start, double []d) 325 { 326 return Math.sqrt(var(start,d)); 327 } 328 329 public static double sd(int start, int end, double []d) 330 { 331 return Math.sqrt(var(start,end,d)); 332 } 333 334 335 /** 336 * compute the variance of the vector 337 * 338 * @param vector 339 * @return variance 340 */ 341 public static double var(double []d) 342 { 343 double tmp=0.0; 344 double mean=mean(d); 345 for( double a : d) 346 { 347 tmp+=(a-mean)*(a-mean); 348 } 349 tmp/=(double)(d.length-1); 350 return tmp; 351 } 352 353 /** 354 * compute the variance of the vector starting at index start 355 * 356 * @param vector 357 * @return variance 358 */ 359 public static double var(int start, double []d) 360 { 361 double tmp=0.0; 362 double mean=mean(start, d); 363 for(int i=start; i< d.length; i++) 364 { 365 tmp+=(d[i]-mean)*(d[i]-mean); 366 } 367 tmp/=(double)(d.length-start-1); 368 return tmp; 369 } 370 371 /** 372 * 373 * compute the variance of the vector starting at index start, ending at end index inclusively 374 * @param start id 375 * @param end id 376 * @param vector 377 * @return variance 378 */ 379 public static double var(int start, int end, double []d) 380 { 381 double tmp=0.0; 382 double mean=mean(start, d); 383 for(int i=start; i <= end ; i++) 384 { 385 tmp+=(d[i]-mean)*(d[i]-mean); 386 } 387 tmp/=(double)(end-start); 388 return tmp; 389 } 390 391 392 /** 393 * Same as var function, except mean is computed 394 * 395 * @param d 396 * @return mean 397 */ 398 public static double mean(double []d) 399 { 400 double tmp=0.0; 401 for( double a : d) 402 { 403 tmp+=a; 404 } 405 tmp/=(double)d.length; 406 return tmp; 407 } 408 409 /** 410 * Same as var function, except mean is computed 411 * 412 * @param start id 413 * @param mean 414 * @return 415 */ 416 public static double mean(int start, double []d) 417 { 418 double tmp=0.0; 419 for( int i = start; i< d.length; i++) 420 { 421 tmp+=d[i]; 422 } 423 tmp/=(double)(d.length- start); 424 return tmp; 425 } 426 427 /** 428 * 429 * Same as var function, except mean is computed 430 * @param start 431 * @param end 432 * @param d 433 * @return 434 */ 435 public static double mean(int start, int end, double []d) 436 { 437 double tmp=0.0; 438 for( int i = start; i <= end; i++) 439 { 440 tmp+=d[i]; 441 } 442 tmp/=(double)(end - start + 1); 443 return tmp; 444 } 445 446 /** 447 * compute the difference of vector one and vector two 448 * 449 * @param vector one 450 * @param vector two 451 * @return vector 452 */ 453 public static double[] diff(double []d, double []e) 454 { 455 if(d.length!=e.length) throw new RuntimeException("array of same size is expected"); 456 double [] tmp= new double [d.length]; 457 for( int i = 0; i < d.length; i++) 458 { 459 tmp[i] = d[i]-e[i]; 460 } 461 return tmp; 462 } 463 464 @Deprecated 465 public static String Pout(double []coefficients) 466 { 467 String ans=""; 468 if(coefficients.length>0) 469 ans+=coefficients[0]; 470 471 for(int a=1;a<coefficients.length;a++) 472 { 473 if(coefficients[a]!=0.0) 474 ans+=" + " + coefficients[a] + "*x^" + a; 475 } 476 return ans; 477 } 478 479 @Deprecated 480 public static String RPout(double []coefficients) 481 { 482 String ans=""; 483 if(coefficients.length>0) 484 ans+=coefficients[coefficients.length-1]; 485 486 for(int a=coefficients.length-2; a>=0; a--) 487 { 488 if(coefficients[a]!=0.0) 489 ans+=" + " + coefficients[a] + "*x^" + (coefficients.length-a-1); 490 } 491 return ans; 492 } 493 494 @Deprecated 495 public static double evaluate(double []coefficients, double x) 496 { 497 double sum=0.0; 498 sum = coefficients[coefficients.length-1]; 499 for(int exponent=coefficients.length-2 ;exponent >= 0;exponent--) 500 { 501 sum = x*sum+coefficients[exponent]; 502 } 503 return sum; 504 } 505 506 @Deprecated 507 public static double[] talorShiftOne(double []out) //g(x)=f(x+1) 508 { 509 //double [] out = new double[coefficients.length]; 510 int last = out.length-1; 511// out[last] = out[last]; 512 for(int i=1; i< out.length; i++) 513 { 514 double tmpcof = out[last-i]; 515 out[last-i] = out[last-i+1]; 516 517 double tmp= out[last]; 518 double tmp2= out[last-1]; 519 520 for(int j=1; j<i; j++) 521 { 522 out[last-j] = out[last-j]+tmp; 523 tmp=tmp2; 524 tmp2=out[last-j-1]; 525 } 526 out[last] = out[last]+tmpcof; 527// for(int j=0;j<i+1;j++) 528// System.out.print(out[last-j]+" "); 529// System.out.println(); 530 } 531 return out; 532 } 533 534 @Deprecated 535 public static double[] RtalorShiftOne(double []out) //g(x)=f(x+1) 536 { 537 //double [] out = new double[coefficients.length]; 538 int last = out.length-1; 539// out[last] = out[last]; 540 for(int i=1; i< out.length; i++) 541 { 542 double tmpcof = out[i]; 543 out[i] = out[i-1]; 544 545 double tmp= out[0]; 546 double tmp2= out[1]; 547 548 for(int j=1; j<i; j++) 549 { 550 out[j] = out[j]+tmp; 551 tmp=tmp2; 552 tmp2=out[j+1]; 553 } 554 out[0] = out[0]+tmpcof; 555// for(int j=0;j<i+1;j++) 556// System.out.print(out[last-j]+" "); 557// System.out.println(); 558 } 559 return out; 560 } 561 562 @Deprecated 563 public static double[] talorShiftNegOne(double []out) //g(x)=f(x+1) 564 { 565 //double [] out = new double[coefficients.length]; 566 int last = out.length-1; 567// out[last] = out[last]; 568 for(int i=1; i< out.length; i++) 569 { 570 double tmpcof = out[last-i]; 571 out[last-i] = out[last-i+1]; 572 573 double tmp= out[last]; 574 double tmp2= out[last-1]; 575 576 for(int j=1; j<i; j++) 577 { 578 out[last-j] = -out[last-j]+tmp; 579 tmp=tmp2; 580 tmp2=out[last-j-1]; 581 } 582 out[last] = -out[last]+tmpcof; 583// for(int j=0;j<i+1;j++) 584// System.out.print(out[last-j]+" "); 585// System.out.println(); 586 } 587 return out; 588 } 589 590 @Deprecated 591 public static double[] RtalorShiftNegOne(double []out) //g(x)=f(x+1) 592 { 593 //double [] out = new double[coefficients.length]; 594 int last = out.length-1; 595// out[last] = out[last]; 596 for(int i=1; i< out.length; i++) 597 { 598 double tmpcof = out[i]; 599 out[i] = out[i-1]; 600 601 double tmp= out[0]; 602 double tmp2= out[1]; 603 604 for(int j=1; j<i; j++) 605 { 606 out[j] = -out[j]+tmp; 607 tmp=tmp2; 608 tmp2=out[j+1]; 609 } 610 out[0] = -out[0]+tmpcof; 611// for(int j=0;j<i+1;j++) 612// System.out.print(out[last-j]+" "); 613// System.out.println(); 614 } 615 return out; 616 } 617 618 @Deprecated 619 public static double [] H(double []out, double n) //g(x)=f(nx) 620 { 621 if(n==1.0)return reverse(out); 622 int last = out.length-1; 623 for(int i=1; i< out.length; i++) 624 { 625 double tmpcof = out[last-i]; 626 for(int j=i; j>= 1; j--) 627 { 628 out[last-j] = out[last-j+1]*n; 629 } 630 out[last] = tmpcof; 631 /* 632 for(int j=0;j<i+1;j++) 633 System.out.print(out[j]+" "); 634 System.out.println(); 635 */ 636 } 637 return out; 638 } 639 640 @Deprecated 641 public static double [] RH(double []out, double n) //g(x)=f(nx) 642 { 643 if(n==1.0)return reverse(out); 644 int last = out.length-1; 645 for(int i=1; i< out.length; i++) 646 { 647 double tmpcof = out[i]; 648 for(int j=i; j>= 1; j--) 649 { 650 out[j] = out[j-1]*n; 651 } 652 out[0] = tmpcof; 653 /* 654 for(int j=0;j<i+1;j++) 655 System.out.print(out[j]+" "); 656 System.out.println(); 657 */ 658 } 659 return out; 660 } 661 662 @Deprecated 663 public static int count(double []coefficients) { 664 int count=0; 665 boolean lastNeg=false; 666 boolean lastPos=false; 667 668 if(coefficients[0]>0) 669 lastPos=true; 670 else if(coefficients[0]<0) 671 lastNeg=true; 672 673 674 for(int i=1; i< coefficients.length; i++) 675 { 676 if(coefficients[i]>0&&lastNeg){ 677 count++; 678 lastPos=true; 679 lastNeg=false; 680 } 681 else if(coefficients[i]<0&&lastPos){ 682 count++; 683 lastPos=false; 684 lastNeg=true; 685 } 686 else if(coefficients[i]<0&&!lastPos){ 687 lastNeg=true; 688 } 689 else if(coefficients[i]>0&&!lastNeg){ 690 lastPos=true; 691 } 692 } 693 return count; 694 } 695 696 @Deprecated 697 public static double [] scale(double []out, double n) 698 { 699 for(int i=0;i<out.length;i++)out[i]*=n; 700 return out; 701 } 702 703 @Deprecated 704 public static double pow2(int expo) 705 { 706 if(expo>0) 707 { 708 return (double)(1<<expo); 709 } 710 else if(expo<0) 711 { 712 return 1.0/((double)(1<<(-expo))); 713 } 714 else 715 { 716 return 1.0; 717 } 718 } 719 720 @Deprecated 721 public static double[] df(double []coefficients) 722 { 723 double[] dPrimeCoefs=new double[coefficients.length-1]; 724 for(int a=1;a<coefficients.length;a++) 725 { 726 dPrimeCoefs[a-1]=coefficients[a]*(double)a; 727 } 728 return dPrimeCoefs; 729 } 730 731 @Deprecated 732 public static int desBound(double []coefficients) { 733 double [] out = new double[coefficients.length]; 734 System.arraycopy(coefficients,0,out,0,coefficients.length); 735 return count(RtalorShiftOne(out)); 736 } 737 738 @Deprecated 739 public static double smallestRoot(double []coefficients) { // return the smallerst Root in interval (0,1) or -1.0 for no root 740 if(count(coefficients)==0)return -1.0; 741// System.out.println("root of "+Pout(coefficients)); 742 TreeSet<KCelement> poolKC = new TreeSet<KCelement>(); 743 poolKC.add(new KCelement(0,0)); 744 double [] Q = new double [coefficients.length]; 745 System.arraycopy(coefficients,0,Q,0,coefficients.length); 746 747 KCelement first,old; 748 old = new KCelement(0,0); 749 750 while((first=poolKC.pollFirst())!=null) 751 { 752 if(first.k==32){ 753 throw new RuntimeException("k:"+first.k+"c:"+first.c+" poly:"+Pout(coefficients)); 754 //continue; //it is a mutiply root 755 } 756// System.out.println(first); 757// System.out.println(Pout(Q)); 758 if((int)(pow2(old.k-first.k)*(double)first.c-old.c)==1) 759 { 760 Q = (scale(RH(talorShiftOne(Q),pow2(old.k-first.k)),pow2(((coefficients.length-1)*(first.k-old.k))))); 761 // Q = Q.talorShiftOne().H(pow2(old.k-first.k)).scale(pow2(((coefficients.length-1)*(first.k-old.k)))); 762 } 763 else if((int)(pow2(old.k-first.k)*(double)first.c-old.c)==0) 764 { 765 Q = reverse(scale(H(Q,pow2(old.k-first.k)),pow2(((coefficients.length-1)*(first.k-old.k))))); 766 // Q = Q.H(pow2(old.k-first.k)).scale(pow2(((coefficients.length-1)*(first.k-old.k)))); 767 } 768 else 769 { 770 throw new RuntimeException("no shift ("+first.c+","+first.k+") old kc ("+old.c+","+old.k+")"); 771 } 772 773 int countRoot = desBound(Q); 774// System.out.println("desBound count:"+countRoot); 775 if(countRoot ==1) 776 { 777// System.out.println("left:"+(double)first.c/(double)(1<<first.k)+" right:"+(double)(first.c+1)/(double)(1<<first.k)); 778// 779 return safeRootFind(coefficients, (double)first.c/(double)(1<<first.k) ,(double)(first.c+1)/(double)(1<<first.k)); 780 } 781 else if (countRoot >1) 782 { 783 if(Math.abs(evaluate(Q,0.5))<minAccuracy)return (2*(double)first.c+1.0)/(double)(1<<first.k+1); 784 poolKC.add(new KCelement(2*first.c,first.k+1)); 785 poolKC.add(new KCelement(2*first.c+1,first.k+1)); 786// System.out.println("add two size "+poolKC.size()); 787 788 } 789 old = first; 790 } 791// System.out.println("not found"); 792 return -1.0; 793 } 794 795 @Deprecated 796 public static double safeRootFind(double[] Q, double guess, double end) 797 { 798 double [] dQ= df(Q); 799 int MAXIT=100; 800 double f1,fh; 801 double xl,xh; 802 f1=evaluate(Q,guess); 803 fh=evaluate(Q,end); 804 if( (f1>0 && fh >0) || (f1<0 && fh <0) )throw new RuntimeException("not bracketed"); 805 if(Math.abs(f1)<minAccuracy)return guess; 806 //if(Math.abs(fh)<minAccuracy)return end; 807 if(f1 <0.0) 808 { 809 xl=guess; 810 xh=end; 811 } 812 else 813 { 814 xh=guess; 815 xl=end; 816 } 817 double rts = 0.5*(xl+xh); 818 double fvalue=evaluate(Q,rts); 819 double dfvalue=evaluate(dQ,rts); 820 double dxold = Math.abs(xh-xl); 821 double dx=dxold; 822 double temp; 823 for( int j=0; j< MAXIT; j++) 824 { 825 if((((rts-xh)*dfvalue-fvalue)*((rts-xl)*dfvalue-fvalue)>0.0) || (Math.abs(2.0*fvalue) > Math.abs(dxold*dfvalue))) //out of range or slow convergent then bisection 826 { 827 dxold = dx; 828 dx=0.5*(xh-xl); 829 rts=xl+dx; 830 if(xl == rts) return rts; 831 } 832 else //Newton method 833 { 834 dxold=dx; 835 dx = fvalue/dfvalue; 836 temp = rts; 837 rts -= dx; 838 if(temp == rts) return rts; 839 } 840 if( Math.abs(dx)<minAccuracy) return rts; 841 fvalue=evaluate(Q,rts); 842 dfvalue=evaluate(dQ,rts); 843 if( fvalue<0) 844 { 845 xl=rts; 846 } 847 else 848 { 849 xh=rts; 850 } 851 } 852 throw new RuntimeException("max iteration"); 853 // return 0.0; 854 } 855 @Deprecated 856 public static double [] reverse(double []out) { 857 int i = 0; 858 int j = out.length - 1; 859 double tmp; 860 while (j > i) { 861 tmp = out[j]; 862 out[j] = out[i]; 863 out[i] = tmp; 864 j--; 865 i++; 866 } 867 return out; 868 } 869 870 @Deprecated 871 public static double largestRoot(double [] out) // return the largest Root in interval (0,1) or -1.0 for no root 872 { 873 if(count(out)==0) 874 { 875 return -1.0; 876 } 877 else 878 { 879 double smallest=smallestRoot(reverse(talorShiftNegOne(reflex(out)))); 880 if(smallest<0.0) 881 { 882 return -1.0; 883 } 884 else 885 { 886 return 1.0- smallest; 887 } 888 } 889 } 890 891 @Deprecated 892 public static double [] reflex(double [] out) 893 { 894 for( int i=1; i< out.length; i+=2) 895 { 896 out[i]=-out[i]; 897 } 898 return out; 899 } 900 901 @Deprecated 902 public static double quickNewton(double [] Q, double guess) 903 { 904 double [] dQ= df(Q); 905 double fvalue=evaluate(Q,guess); 906 double dfvalue=evaluate(dQ,guess); 907 if(dfvalue>0.0)return largestRoot(Q); 908// System.out.println("f:"+fvalue); 909// System.out.println("df:"+dfvalue); 910// System.out.println("dx:"+(fvalue/dfvalue)); 911 double dx; 912 do 913 { 914 dx = fvalue/dfvalue; 915 guess -= dx; 916 fvalue=evaluate(Q,guess); 917 dfvalue=evaluate(dQ,guess); 918// if(dfvalue>0.0)return largestRoot(Q); 919 if(dfvalue>0.0)return -1.0; 920 /* 921// for check accuracy 922 if(dfvalue>0.0) 923 { 924 double result = largestRoot(Q); 925 if(result != -1.0) throw new RuntimeException("exception is met for quickNetwon"); 926 return -1.0; 927 } 928 */ 929 } while(Math.abs(fvalue)>minAccuracy); 930 return guess; 931 } 932 /** 933 * compute greatest common factor for two numbers 934 * 935 * @param a 936 * @return 937 */ 938 public static int gcd(int a, int b) 939 { 940 int maxI,minI; 941 if(a>b) 942 { 943 maxI = a; 944 minI = b; 945 } 946 else 947 { 948 maxI = b; 949 minI = a; 950 } 951 int residule; 952 do 953 { 954 residule = (maxI % minI); 955 maxI = minI; 956 minI = residule; 957 958 }while(residule != 0); 959 return maxI; 960 } 961 962 /** 963 * compute greatest common factor for an array of integers. 964 * 965 * @param a 966 * @return 967 */ 968 public static int gcd(int []a) 969 { 970 if(a.length<2) throw new RuntimeException("array length no less than 2"); 971 int cd = a[0]; 972 for(int i=1; i<a.length; i++) 973 { 974 cd = gcd(cd,a[i]); 975 } 976 return cd; 977 } 978 979 /** 980 * print array 981 * 982 * @param a 983 */ 984 public static void printA (int []a) 985 { 986 for(int i=0;i<a.length;i++) 987 { 988 System.out.print(a[i]+" "); 989 } 990 } 991 992 /** 993 * print array 994 * 995 * @param a 996 */ 997 public static void printlnA (int []a) 998 { 999 for(int i=0;i<a.length;i++) 1000 { 1001 System.out.print(a[i]+" "); 1002 } 1003 System.out.println(); 1004 } 1005 1006}