2d DCT program not working - java

I have to do this 2d DCT of an image for my project.
I translated the formula right to code. It all seems fine logically but it doesn't give the required result. I've tallied it with matlab function to check the results for a 3x3 matrix but they are incorrect.
Also, what and how I've coded gives a huge number of loops such that an actual image operation takes hours to compute.
Any suggestion to reduce the loops and pointing of program error would be great.
Thanks.
This is my code.
double alpha_p, alpha_q;
double pi = Math.atan(1.0) * 4.0;
//dct begins
System.out.println("it begins");
for (int p = 0; p < M; p++) {
for (int q = 0; q < N; q++) {
if (p == 0)
alpha_p = 1 / sqrt(M);
else
alpha_p = sqrt(2 / M);
if (q == 0)
alpha_q = 1 / sqrt(N);
else
alpha_q = sqrt(2 / N);
double toreturn = 0;
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n++) {
toreturn = toreturn + img[m][n]
* cos(((2 * m + 1) * p * pi) / 2 * M)
* cos(((2 * n + 1) * q * pi) / 2 * N);
}
}
dctimg[p][q] = alpha_p * alpha_q * toreturn;
System.out.println("euta");
}
}
// dct over
System.out.println("its over");
//inverse dct begins
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n++) {
double toreturn = 0;
for (int p = 0; p < M; p++) {
for (int q = 0; q < N; q++) {
if (p == 0)
alpha_p = 1 / sqrt(M);
else
alpha_p = sqrt(2 / M);
if (q == 0)
alpha_q = 1 / sqrt(N);
else
alpha_q = sqrt(2 / N);
toreturn = toreturn + alpha_p * alpha_q * dctimg[p][q]
* cos(((2 * m + 1) * p * pi) / 2 * M)
* cos(((2 * n + 1) * q * pi) / 2 * N);
}
}
finalimg[m][n] = toreturn;
}
}
//inverse dct over

First of all, in the formula of DCT the denominator of cos is 2 * M. It is a typical mistake. 4 / 2 * 2 = 4 not 1
cos(((2 * m + 1) * p * pi) / 2 * M) should be cos(((2 * m + 1) * p * pi) / (2 * M))
Parentheses are required in all four cases.
Another moment that I want to mention is sqrt(2 / M). If M has an integer type (it is not clear by your code) and it is greater than 2, then the expression 2 / M is equal to 0. Because both operands have integer types and / gives only integer part. To fix it, add a floating point like that sqrt(2.0 / M).
As you have already noticed, there is a lot of loops, in other words, the complexity of the 2D DCT II is O(n^4).
In real life nobody applies DCT to the whole actual image. The image is split into blocks of size 8x8 and each block is processed by DCT. This approach allows to keep n low and the complexity becomes acceptable.
To decrease the algorithmic complexity, I want to link here, where methods of using 1D DCT and FFT are good explained.

Related

How to implement arctan function in Java?

Function to implement
Code
public class arctan {
public static double arctan(double x) {
double sum = 0;
int k = 0;
double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
for (int i = k; i < 100; i++) {
sum =+ arctan1;
}
return (double) arctan1;
}
}
Issue
My program just gives back my x as output. I don't see the mistake I am doing.
You have to put double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1))); in the loop as well since that is what the Σ is doing in the formula.
You also didn't need to have a new variable i in the for loop in this case. Using k like the formula is fine.
So it would be like this instead:
public class arctan {
public static double arctan(double x) {
double sum = 0;
for (int k = 0; k < 100; i++) {
sum += (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
}
return sum;
}
}
What does the letter Σ (sum over) mean?
See Wikipedia about the mathematical sum-symbol (uppercase sigma in Greek alphabet): Σ.
In you case it is the sum over a range from k = 0 until k = infinite.
The sum of the term following the sigma.
Define it as function instead variable
The term following is implemented correctly by:
double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
Extract it as function of k and x:
public static double arctan1(int k, double x) {
return ( Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1) ));
}
Because the calculation is depending on inputs k and x now, you can use it in your sum-over range of k:
// Note: the limit is 99 here, not infinite
for (int k = 0; k < 100; k++) {
sum += arctan1( k,x ); // increasing k used as input
}
Put it all together
// your "term following the sum-over" implemented by function arctan1(int k, double x)
public static double arctan(double x) {
double sum = 0;
// your loop to sum-up for increasing k
return sum;
}

Change function for binomial polynome so that it output reverse arrays

I have a method for binomial polynome, however I want it to output an array in a reverse order. I can reverse arrays after the method, but that isn't very effective.
Can you help me?
public double[] binomialPolynome(int i, int j) {
int power = 0;
if (maxPower[i] < j) {
power = maxPower[i];
} else {
power = j;
}
double[] result = new double[power + 1];
for (int k = 0; k < result.length; k++) {
result[k] = factorial(power) / (factorial(k) * factorial(power - k))
* Math.pow(-xPoints[i], k);
}
return result;
}
If you can consider substituting double[] for Double [], you can easily achieve this by:
Collections.reverse(Arrays.asList(result));
System.out.println(Arrays.asList(result));
You can populate the result array from right to left, rather than left to right.
result[k] = factorial(power) / (factorial(k) * factorial(power - k))
* Math.pow(-xPoints[i], k);
Becomes:
result[result.length-1-k] = factorial(power) / (factorial(k) * factorial(power - k))
* Math.pow(-xPoints[i], k);
or even just
result[power-k] = factorial(power) / (factorial(k) * factorial(power - k))
* Math.pow(-xPoints[i], k);
Since result.length = power+1

Return how many terms are necessary entering a level of precision, e.g .001, to come within the specified precision of the value of PI?

Problem: Interactively enter a level of precision, e.g., .001, and then report how many terms are necessary for each of these estimates to come within the specified precision of the value of pi.
My Solution So Far:
Current result does not terminate. The PIEstimator class driver is given. The problem lies inside the PIEstimates class. Some specific questions that I have:
How do you calculate Wallis PI and Leibniz PI in code? The ways for calculating each arithmetically for Wallis is:
pi/4 = (2/3)(4/3)(4/5)(6/5)(6/7)(8/7)(8/9)*...
and for Leibniz:
pi/4 = (1 - 1/3 + 1/5 - 1/7 + 1/9 ...)
Is the current logic of doing this code correct so far? Using a while loop to check if the respective PI calculation is within the limits, with a for loop inside continuing to run until the while requirements are met. Then there is a count that returns the number of times the loop repeated.
For .001, for example, how many terms does it take for each of these formulas to reach a value between 3.14059.. and 3.14259...
import java.util.Scanner;
public class PiEstimator {
public static void main(String[] args) {
System.out.println("Wallis vs Leibnitz:");
System.out.println("Terms needed to estimate pi");
System.out.println("Enter precision sought");
Scanner scan = new Scanner(System.in);
double tolerance = scan.nextDouble();
PiEstimates e = new PiEstimates(tolerance);
System.out.println("Wallis: " + e.wallisEstimate());
System.out.println("Leibnitz: " + e.leibnitzEstimate());
}
}
public class PiEstimates {
double n = 0.0;
double upperLim = 0;
double lowerLim = 0;
public PiEstimates(double tolerance) {
n = tolerance;
upperLim = Math.PI+n;
lowerLim = Math.PI-n;
}
public double wallisEstimate() {
double wallisPi = 4;
int count = 0;
while(wallisPi > upperLim || wallisPi < lowerLim) {
for (int i = 3; i <= n + 2; i += 2) {
wallisPi = wallisPi * ((i - 1) / i) * ((i + 1) / i);
}
count++;
}
return count;
}
public double leibnitzEstimate() {
int b = 1;
double leibnizPi = 0;
int count = 0;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
for (int i = 1; i < 1000; i += 2) {
leibnizPi += (4/i - 4/i+2);
}
b = -b;
count++;
}
return count;
}
}
At least one mistake in wallisEstimate
for (int i = 3; i <= n + 2; i += 2) {
should be count instead of n:
for (int i = 3; i <= count + 2; i += 2) {
... but still then the algorithm is wrong. This would be better:
public double wallisEstimate() {
double wallisPi = 4;
int count = 0;
int i = 3;
while(wallisPi > upperLim || wallisPi < lowerLim) {
wallisPi = wallisPi * ((i - 1) / i) * ((i + 1) / i);
count++;
i += 2;
}
return count;
}
Similarly, for the Leibniz function:
public double leibnitzEstimate() {
double leibnizPi = 0;
int count = 0;
int i = 1;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
leibnizPi += (4/i - 4/i+2);
count++;
i += 4;
}
return count;
}
For Leibnitz, I think the inner loop should only run count number of times:
for (int i = 1; i < count; i += 2) {
leibnizPi += (4/i - 4/i+2);
}
If it runs 1000 times every time you can't know when pi was in range.
If the while loops don't terminate, then they don't approach PI.
Wallis: pi/4 = (2/3)(4/3)(4/5)(6/5)(6/7)(8/7)(8/9)*...
The while loop would restart the for loop at i = 3 which would keep adding the same sequence of terms, rather than progressing along with the pattern.
Here's a draft of an alternative solution (no pun intended) based on the pattern of terms.
As you see, the numerators repeat, except for the 2. The divisors repeat aswell, but offset from the numerators: they increment in an alternating fashion.
This way you can actually count each individual terms, instead of pairs of them.
public double wallisEstimate() {
double wallisPi = 1;
int count = 0;
double numerator = 2;
double divisor = 3;
while(wallisPi > upperLim || wallisPi < lowerLim) {
wallisPi *= numerator / divisor;
if ( count++ & 1 == 0 )
numerator+=2;
else
divisor+=2;
}
return count;
}
There is one more change to make, and that is in the initialisation of upperLim and lowerLim. The algorithm approaches PI/2, so:
upperLim = (Math.PI + tolerance)/2;
lowerLim = (Math.PI - tolerance)/2;
Leibniz: pi/4 = (1 - 1/3 + 1/5 - 1/7 + 1/9 ...)
Here the for loop is also unwanted: at best, you will be counting increments of 2000 terms at a time.
The pattern becomes obvious if you write it like this:
1/1 - 1/3 + 1/5 - 1/7 ...
The divisor increments by 2 for every next term.
public double leibnitzEstimate() {
double leibnizPi = 0;
int divisor = 1;
int count = 0;
while(leibnizPi > upperLim || leibnizPi < lowerLim) {
leibnizPi += 1.0 / divisor;
divisor = -( divisor + 2 );
count++;
}
return count;
}
The update of leibnizPi can also be written like this:
leibnizPi += sign * 1.0 / divisor;
divisor += 2;
sign = -sign;
which is more clear, takes one more variable and one more instruction.
An update to the upperLim and lowerLim must be made here aswell: the algorithm approaches PI/4 (different from Leibniz!), so:
upperLim = (Math.PI + tolerance)/4;
lowerLim = (Math.PI - tolerance)/4;

Printing a frame within frame

I got this assignment in Java and I don't have a single clue on how to do it.
The task is to receive an integer n > 0, and to print n number of frames constructed by * inside each other, while the inner frame will have the letter "X" constructed by 4n+1 *.
I can't use arrays or strings.
For example:
n=1 will print:
*******
* *
* * * *
* * *
* * * *
* *
*******
n=2 will print:
*************
* *
* ********* *
* * * *
* * * * * *
* * * * * *
* * * * *
* * * * * *
* * * * * *
* * * *
* ********* *
* *
*************
This is what I have so far:
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int size = n * 6 + 1;
int x = 1;
int y = 1;
for (int i = 0; i < n; i = i + 1) {
for (int i3 = 0; i3 < size; i3 = i3 + 1) {
System.out.print("*");
}
System.out.println("");
y = y + 1;
for (int i1 = 0; i1 < size - 2; i1 = i1 + 1) {
System.out.print("*");
for (int i2 = 0; i2 < size - 2; i2 = i2 + 1) {
System.out.print(" ");
}
System.out.println("*");
y = y + 1;
}
for (int i4 = 0; i4 < size; i4 = i4 + 1) {
System.out.print("*");
}
}
There are many different approaches to this problem. This may not be the best, but it's quite simple and educational IMO.
The main idea is: you don't need to know how to print the entire frame. You only need to know how to print 1/4 of it - then repeat it in reverse X order, then repeat it in reverse Y order. Let's start with drawing X, specifically - one diagonal of it. If the "X" has to have 4n+1 *, it has 4 arms with a stars each and one * in the middle - totaling to 4 * a + 1 stars - so, obviously, 4n+1 == 4a+1, and each arm has to have exactly n *'s. Let's use XY Cartesian coordinate system. Thus, we only have an asterisk if x == y - otherwise we have s space there.
for ( int y = 0; y < n; y++ ) {
for ( int x = 0; x < n; x++ ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
System.out.println();
}
Now, let's add a mirror copy to it by iterating in reverse too:
for ( int y = 0; y < n; y++ ) {
for ( int x = 0; x < n; x++ ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
for ( int x = n; x >= 0; x-- ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
System.out.println();
}
Now, let's try to get into valid Cartesian:
int x, y;
for ( y = -n; y <= n; y++ ) {
for ( x = -n; x < 0; x++ ) {
System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
}
for ( ; x <= n; x++ ) {
System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
}
System.out.println();
}
and, finally, we can figure that it's just
for ( int y = -n; y <= n; y++ ) {
for ( int x = -n; x <= n; x++ ) {
System.out.print( hasAsterisk( Math.abs(x), Math.abs(y) ) ? '*' : ' ' );
}
System.out.println();
}
with, for example
static boolean hasAsterisk( int x, int y ) {
return x == y;
}
Extend this code to handle the frames, and you're set. Each "quart part" of the frame is only * for each n, 2n chars total - the cross itself is n in length (see above) plus 1 central asterisk; to sum up, X and Y will range over int [-3n,3n] - call that 3n some m and use it as the range for iteration.
As an additional hint, the formula is different for the inner cross (i.e. abs(x)<n,abs(y)<n), and different for the frames themselves. The formula for the frames can be easily figured out if you notice that it's every second row, in the shape of two asterisk triangles in axis X added to two triangles in axis Y.
return ( x <= n && y <= n ) ? x == y : ( ( x < y ) ? y % 2 == nMod2 : x % 2 == nMod2 );

ANSI C pointers to java

Since some weeks ago I have been trying to convert this c and other c function to java language (i'm a newbie on it).
My first problem is how-to convert to java code, the pointers on lines like:
q = fdata + ind;
datend = fdata + buff_size;
For example when "ind" has a negative position (-220 for example) the pointer will be on "ind" position before "fdata" values, also the same occur with datend var.
I figured out that can be solved on isolated way by creating an index var for each pointer to know where there are pointing at. The real problem for me comes a few line after that, when i trying to not run over end of frame of "fdata" array.
Can some body with more experiences help me please?
Thank.
static Stat *stat = NULL;
static float *mem = NULL;
static Stat*
get_stationarity(fdata, freq, buff_size, nframes, frame_step, first_time)
float *fdata;
double freq;
int buff_size, nframes, frame_step, first_time;
{
static int nframes_old = 0, memsize;
float preemp = 0.4f, stab = 30.0f;
float *p, *q, *r, *datend;
int ind, i, j, m, size, order, agap, w_type = 3;
agap = (int) (STAT_AINT * freq);
size = (int) (STAT_WSIZE * freq);
ind = (agap - size) / 2;
if (nframes_old < nframes || !stat || first_time) {
/* move this to init_dp_f0() later */
nframes_old = nframes;
if (stat) {
ckfree((char *) stat->stat);
ckfree((char *) stat->rms);
ckfree((char *) stat->rms_ratio);
ckfree((char *) stat);
}
if (mem) ckfree((void *) mem);
stat = (Stat *) ckalloc(sizeof (Stat));
stat->stat = (float*) ckalloc(sizeof (float) *nframes);
stat->rms = (float*) ckalloc(sizeof (float) *nframes);
stat->rms_ratio = (float*) ckalloc(sizeof (float) *nframes);
memsize = (int) (STAT_WSIZE * freq) + (int) (STAT_AINT * freq);
mem = (float *) ckalloc(sizeof (float) * memsize);
for (j = 0; j < memsize; j++) mem[j] = 0;
}
if (nframes == 0) return (stat);
q = fdata + ind;
datend = fdata + buff_size;
if ((order = (int) (2.0 + (freq / 1000.0))) > BIGSORD) {
fprintf(stderr,
"exceeds that allowable (%d); reduce Fs\n", BIGSORD);
order = BIGSORD;
}
/* prepare for the first frame */
for (j = memsize / 2, i = 0; j < memsize; j++, i++) mem[j] = fdata[i];
/* do not run over end of frame */
for (j = 0, p = q - agap; j < nframes; j++, p += frame_step, q += frame_step) {
if ((p >= fdata) && (q >= fdata) && (q + size <= datend))
stat->stat[j] = get_similarity(order, size, p, q,
&(stat->rms[j]),
&(stat->rms_ratio[j]), preemp,
stab, w_type, 0);
else {
if (first_time) {
if ((p < fdata) && (q >= fdata) && (q + size <= datend))
stat->stat[j] = get_similarity(order, size, NULL, q,
&(stat->rms[j]),
&(stat->rms_ratio[j]),
preemp, stab, w_type, 1);
else {
stat->rms[j] = 0.0;
stat->stat[j] = 0.01f * 0.2f; /* a big transition */
stat->rms_ratio[j] = 1.0; /* no amplitude change */
}
} else {
if ((p < fdata) && (q + size <= datend)) {
stat->stat[j] = get_similarity(order, size, mem,
mem + (memsize / 2) + ind,
&(stat->rms[j]),
&(stat->rms_ratio[j]),
preemp, stab, w_type, 0);
/* prepare for the next frame_step if needed */
if (p + frame_step < fdata) {
for (m = 0; m < (memsize - frame_step); m++)
mem[m] = mem[m + frame_step];
r = q + size;
for (m = 0; m < frame_step; m++)
mem[memsize - frame_step + m] = *r++;
}
}
}
}
}
/* last frame, prepare for next call */
for (j = (memsize / 2) - 1, p = fdata + (nframes * frame_step) - 1; j >= 0 && p >= fdata; j--)
mem[j] = *p--;
return (stat);
}
This code is easier rewritten than ported. The reason is, that it uses a large number of pointer-arithmetic and casting.
It looks to me like this code combines a sliding window and averaging functions over the data. You can easily do this in Java, just place each time-series in an array, use an index (instead of a pointer) to point at the array's entries. In the case where the C-code uses a pointer and then a (possibly negative) offset as a second pointer just use two indices into the time-series-array.
It is easier to do this if you have the formula (math-notation. sliding-window plus averaging functions) that this code is supposed to compute and translate the formula to java.

Categories