Source code: java/net/LinearInterpolator.java
1 /* ZNet - Java Compression Layer for a new Socket Factory
2 Copyright (C) 1999, Free Software Rulez
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18 The author of this program may be contacted at morgiaclaudio@yahoo.it. */
19
20 package java.net;
21
22 /**
23 * This class is an implementation of the {@link java.net.Interpolator Interpolator} interface and it uses
24 * a statistical approach called <b>fixed point interpolation</b> that I created during my master degree thesis.
25 * The transmission line model and the level model are described by a linear curve like the following:<br>
26 * <code aling="center">y=A*x+b</code><br>
27 * The model is composed of two interpolation curve:<ul>
28 * <li>the first is used for the compression time
29 * <li>the second is used for the compression ratio
30 * </ul>
31 * The model is completed by the preceding sample point. So every model keeps five coefficients: A and B
32 * for compression time, A and B for compression ratio, and X for the last sample point.
33 * This interpolator keeps a model for the transmission line and a model for every compression level.
34 * For a complete description of the approach see <a href="mythesis">my thesis</a>.
35 * @see java.net.Interpolator
36 * @author <a href="mailto:morgiaclaudio@yahoo.it">Claudio Morgia</a>
37 * @version 1.0
38 */
39 public class LinearInterpolator implements Interpolator {
40 /**
41 * Data needed to model the transmission line. It's an array composed of five elements.
42 */
43 protected double[] line;
44
45 /**
46 * Data needed to model levels. It's an array with the same number of elements as the supported levels
47 * and every entry is an array of five elements like the {@link #line line} field.
48 */
49 protected double[][] levels;
50
51 /**
52 * The number of supported levels as reported by the compression engine.
53 */
54 protected int num_levels;
55 protected static int At=0,Bt=1,Ac=2,Bc=3,Xprec=4;
56
57 /**
58 * Empty constructor. Don't forget to call {@link #create create}.
59 */
60 public LinearInterpolator() {}
61
62 /**
63 * Real constructor.
64 * @param num the number of supported compression level
65 */
66 public LinearInterpolator(Integer num) {
67 create(num);
68 }
69
70 /**
71 * Entry point for some explicit and synchronous clean up.
72 * @return true if right else false
73 */
74 public boolean destroy() {
75 return true;
76 }
77
78 /**
79 * This method is the real constructor and it's responsible for data allocation and initialization.
80 * @return true if everything was right
81 */
82 public boolean create(Integer num) {
83 num_levels=num.intValue();
84 line=new double[2];
85 levels=new double[num_levels][5];
86 for (int i=0; i<num_levels ;i++) {
87 levels[i][At]=1;
88 levels[i][Bt]=0;
89 levels[i][Ac]=1;
90 levels[i][Bc]=0;
91 levels[i][Xprec]=0;
92 }
93 return true;
94 }
95
96 /**
97 * This method choose the best level to use to compress data based on an iterative algorithm I did in
98 * my thesis.
99 * Basically it's a loop starting from the most compressing level downward and during every step
100 * it calculates a threshold for the level and compares it with the dimension of the object to compress.
101 * If the dimension is over the threshold, the level is selected.<br>
102 * If you are interested in the mathematical background behind the choice, see my {@link mythesis mythesis}.
103 * @param dim dimension of the object to compress
104 * @return the selected level
105 */
106 public int computeLevel(int dim) {
107 double a,b;
108 double[] data;
109 a=line[At];
110 b=line[Bt];
111 for (int i=num_levels-1; i>0; i--) {
112 data=levels[i];
113 if (dim>(a*data[Bc]+data[Bt])/(a*(1-data[Ac])-data[At]))
114 return i;
115 }
116 return 0;
117 }
118
119 /**
120 * This method is responsible for updating the transmission line model.
121 * If you are interested in the mathematical aspect, see my thesis.
122 * @param dim dimension of the object to transmit
123 * @param trans_time the measured transmission time
124 * @param Xprec the last sample point
125 * return true ok, false bad things happened
126 */
127 public boolean updateLine(int dim,double trans_time,double Xprec) {
128 double a,b;
129 a=line[At];
130 b=line[Bt];
131 line[At]=(a*Xprec+b-trans_time)/(Xprec-dim);
132 line[Bt]=(trans_time-a*dim);
133 return true;
134 }
135
136 /**
137 * This method is responsible for updating the selected level model.
138 * If you are interested in the mathematical aspect, see my thesis.
139 * @param level selected working level
140 * @param dim dimension of the object to transmit
141 * @param compress_time the measured compression time
142 * @param compress_dim the measured compression dimension
143 * @param trans_time the measured transmission time
144 * return true ok, false bad things happened
145 */
146 public boolean update(int level,int dim,double compress_time,double compress_dim, double trans_time) {
147 D.p("update level "+level+" for dimension "+dim+" reduced in "+compress_dim+" just in "+compress_time+"ms and transmitted in "+trans_time+" ms");
148 String toPrint=Double.toString((1-(compress_time+trans_time)/((dim/compress_dim)*trans_time))*100);
149 D.p("current efficiency is "+toPrint.substring(0,Math.min(toPrint.length(),toPrint.indexOf('.')+3))+"%");
150 double[] data=levels[level];
151 double a,b,xprec;
152
153 xprec=data[Xprec];
154 updateLine(dim,trans_time,xprec);
155
156 if (level<1) return true;
157
158 a=data[At];
159 b=data[Bt];
160 data[At]=(a*xprec+b-compress_time)/(xprec-compress_time);
161 data[Bt]=(compress_time-a*dim);
162
163 a=data[Ac];
164 b=data[Bc];
165 data[Ac]=(a*xprec+b-compress_dim)/(xprec-compress_dim);
166 data[Bc]=(compress_dim-a*dim);
167
168 data[Xprec]=dim;
169 levels[level]=data;
170 return true;
171 }
172
173 public void finalize() throws Throwable {
174 if (destroy()==false)
175 throw new Exception("Unclean exception.");
176 }
177 }