Beispiel #1
0
  public boolean play() {

    try {
      if (playState != STOPPED) playStop();

      if (audioBytes == null) return false;

      DataLine.Info info = new DataLine.Info(Clip.class, format);

      clip = (Clip) AudioSystem.getLine(info);
      clip.addLineListener(new ClipListener());

      long clipStart = (long) (audioBytes.length * getStartTime() / (getDuration() * 1000.0));
      long clipEnd = (long) (audioBytes.length * getEndTime() / (getDuration() * 1000.0));
      if ((clipEnd - clipStart) > MAX_CLIP_LENGTH) clipEnd = clipStart + MAX_CLIP_LENGTH;
      byte[] clipBytes = new byte[(int) (clipEnd - clipStart)];
      System.arraycopy(audioBytes, (int) clipStart, clipBytes, 0, clipBytes.length);
      clip.open(format, clipBytes, 0, clipBytes.length);

      FloatControl panControl = (FloatControl) clip.getControl(FloatControl.Type.PAN);

      panControl.setValue((float) panSetting / 100.0f);

      double value = (double) gainSetting;

      FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
      float dB = (float) (Math.log(value == 0.0 ? 0.0001 : value) / Math.log(10.0) * 20.0);
      gainControl.setValue(dB);
      double playStartTime = (player.getSeekTime() / 100) * (playGetLength());
      clip.setMicrosecondPosition((long) playStartTime);

      clip.start();

      playState = PLAYING;

      return true;

    } catch (Exception ex) {
      ex.printStackTrace();
      playState = STOPPED;
      clip = null;
      return false;
    }
  }
 public double getValue(DatanVector x) {
   double result;
   double a = sqrt2pi * x.getElement(1);
   if (a < small) f = big;
   else f = Math.log(a);
   result = (double) y.length * f;
   for (int i = 0; i < y.length; i++) {
     f = Math.pow((y[i] - x.getElement(0)), 2.) / (2. * x.getElement(1) * x.getElement(1));
     result += f;
   }
   return result;
 }
  private int percentToZoomLevel(double percent) {
    double minZoomPercent = mImagePresentationModel.getMinZoom();
    double zoomIncrement = computeZoomIncrementToMakeExactlyNIncrements();

    return (int) Math.round((Math.log(percent / minZoomPercent) / Math.log(zoomIncrement)) + 1);
  }
Beispiel #4
0
  /** Translation durchfuehren */
  public void process() {
    int i, j, k;
    int ch, len;
    float f1;
    double d1, d2, d3, d4, d5;
    long progOff, progLen, lo;

    // io
    AudioFile reInF = null;
    AudioFile imInF = null;
    AudioFile reOutF = null;
    AudioFile imOutF = null;
    AudioFileDescr reInStream = null;
    AudioFileDescr imInStream = null;
    AudioFileDescr reOutStream = null;
    AudioFileDescr imOutStream = null;
    FloatFile reFloatF[] = null;
    FloatFile imFloatF[] = null;
    File reTempFile[] = null;
    File imTempFile[] = null;
    int outChanNum;

    float[][] reInBuf; // [ch][i]
    float[][] imInBuf; // [ch][i]
    float[][] reOutBuf = null; // [ch][i]
    float[][] imOutBuf = null; // [ch][i]
    float[] convBuf1, convBuf2;
    boolean complex;

    PathField ggOutput;

    // Synthesize
    Param ampRef = new Param(1.0, Param.ABS_AMP); // transform-Referenz
    float gain; // gain abs amp
    float dryGain, wetGain;
    float inGain;
    float maxAmp = 0.0f;
    Param peakGain;

    int inLength, inOff;
    int pre;
    int post;
    int length;
    int framesRead, framesWritten, outLength;
    boolean polarIn, polarOut;

    // phase unwrapping
    double[] phi;
    int[] wrap;
    double[] carry;

    Param lenRef;

    topLevel:
    try {

      complex = pr.bool[PR_HASIMINPUT] || pr.bool[PR_HASIMOUTPUT];
      polarIn = pr.intg[PR_OPERATOR] == OP_POLAR2RECT;
      polarOut = pr.intg[PR_OPERATOR] == OP_RECT2POLAR;
      if ((polarIn || polarOut) && !complex) throw new IOException(ERR_NOTCOMPLEX);

      // ---- open input ----

      reInF = AudioFile.openAsRead(new File(pr.text[PR_REINPUTFILE]));
      reInStream = reInF.getDescr();
      inLength = (int) reInStream.length;
      reInBuf = new float[reInStream.channels][8192];
      imInBuf = new float[reInStream.channels][8192];

      if (pr.bool[PR_HASIMINPUT]) {
        imInF = AudioFile.openAsRead(new File(pr.text[PR_IMINPUTFILE]));
        imInStream = imInF.getDescr();
        if (imInStream.channels != reInStream.channels) throw new IOException(ERR_COMPLEX);
        inLength = (int) Math.min(inLength, imInStream.length);
      }

      lenRef = new Param(AudioFileDescr.samplesToMillis(reInStream, inLength), Param.ABS_MS);
      d1 =
          AudioFileDescr.millisToSamples(
              reInStream, (Param.transform(pr.para[PR_OFFSET], Param.ABS_MS, lenRef, null).value));
      j = (int) (d1 >= 0.0 ? (d1 + 0.5) : (d1 - 0.5)); // correct rounding for negative values!
      length =
          (int)
              (AudioFileDescr.millisToSamples(
                      reInStream,
                      (Param.transform(pr.para[PR_LENGTH], Param.ABS_MS, lenRef, null)).value)
                  + 0.5);

      // System.err.println( "offset = "+j );

      if (j >= 0) {
        inOff = Math.min(j, inLength);
        if (!pr.bool[PR_REVERSE]) {
          reInF.seekFrame(inOff);
          if (pr.bool[PR_HASIMINPUT]) {
            imInF.seekFrame(inOff);
          }
        }
        inLength -= inOff;
        pre = 0;
      } else {
        inOff = 0;
        pre = Math.min(-j, length);
      }
      inLength = Math.min(inLength, length - pre);
      post = length - pre - inLength;

      if (pr.bool[PR_REVERSE]) {
        i = pre;
        pre = post;
        post = i;
        inOff += inLength;
      }

      // .... check running ....
      if (!threadRunning) break topLevel;

      // for( op = 0; op < 2; op++ ) {
      // 	System.out.println( op +": pre "+pre[op]+" / len "+inLength[op]+" / post "+post[op] );
      // }
      // System.out.println( "tot "+length[0]);

      outLength = length;
      outChanNum = reInStream.channels;

      // ---- open output ----

      ggOutput = (PathField) gui.getItemObj(GG_REOUTPUTFILE);
      if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
      reOutStream = new AudioFileDescr(reInStream);
      ggOutput.fillStream(reOutStream);
      reOutStream.channels = outChanNum;
      // well, more sophisticated code would
      // move and truncate the markers...
      if ((pre == 0) /* && (post == 0) */) {
        reInF.readMarkers();
        reOutStream.setProperty(
            AudioFileDescr.KEY_MARKERS, reInStream.getProperty(AudioFileDescr.KEY_MARKERS));
      }
      reOutF = AudioFile.openAsWrite(reOutStream);
      reOutBuf = new float[outChanNum][8192];
      imOutBuf = new float[outChanNum][8192];

      if (pr.bool[PR_HASIMOUTPUT]) {
        imOutStream = new AudioFileDescr(reInStream);
        ggOutput.fillStream(imOutStream);
        imOutStream.channels = outChanNum;
        imOutStream.file = new File(pr.text[PR_IMOUTPUTFILE]);
        imOutF = AudioFile.openAsWrite(imOutStream);
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Further inits ----

      phi = new double[outChanNum];
      wrap = new int[outChanNum];
      carry = new double[outChanNum];
      for (ch = 0; ch < outChanNum; ch++) {
        phi[ch] = 0.0;
        wrap[ch] = 0;
        carry[ch] = Double.NEGATIVE_INFINITY;
      }

      progOff = 0; // read, transform, write
      progLen = (long) outLength * 3;

      wetGain = (float) (Param.transform(pr.para[PR_WETMIX], Param.ABS_AMP, ampRef, null)).value;
      dryGain = (float) (Param.transform(pr.para[PR_DRYMIX], Param.ABS_AMP, ampRef, null)).value;
      if (pr.bool[PR_DRYINVERT]) {
        dryGain = -dryGain;
      }
      inGain = (float) (Param.transform(pr.para[PR_INPUTGAIN], Param.ABS_AMP, ampRef, null)).value;
      if (pr.bool[PR_INVERT]) {
        inGain = -inGain;
      }

      // normalization requires temp files
      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        reTempFile = new File[outChanNum];
        reFloatF = new FloatFile[outChanNum];
        for (ch = 0;
            ch < outChanNum;
            ch++) { // first zero them because an exception might be thrown
          reTempFile[ch] = null;
          reFloatF[ch] = null;
        }
        for (ch = 0; ch < outChanNum; ch++) {
          reTempFile[ch] = IOUtil.createTempFile();
          reFloatF[ch] = new FloatFile(reTempFile[ch], GenericFile.MODE_OUTPUT);
        }
        if (pr.bool[PR_HASIMOUTPUT]) {
          imTempFile = new File[outChanNum];
          imFloatF = new FloatFile[outChanNum];
          for (ch = 0;
              ch < outChanNum;
              ch++) { // first zero them because an exception might be thrown
            imTempFile[ch] = null;
            imFloatF[ch] = null;
          }
          for (ch = 0; ch < outChanNum; ch++) {
            imTempFile[ch] = IOUtil.createTempFile();
            imFloatF[ch] = new FloatFile(imTempFile[ch], GenericFile.MODE_OUTPUT);
          }
        }
        progLen += outLength;
      } else {
        gain = (float) (Param.transform(pr.para[PR_GAIN], Param.ABS_AMP, ampRef, null)).value;
        wetGain *= gain;
        dryGain *= gain;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ----==================== the real stuff ====================----

      framesRead = 0;
      framesWritten = 0;

      while (threadRunning && (framesWritten < outLength)) {
        // ---- choose chunk len ----
        len = Math.min(8192, outLength - framesWritten);
        if (pre > 0) {
          len = Math.min(len, pre);
        } else if (inLength > 0) {
          len = Math.min(len, inLength);
        } else {
          len = Math.min(len, post);
        }

        // ---- read input chunks ----
        if (pre > 0) {
          Util.clear(reInBuf);
          if (complex) {
            Util.clear(imInBuf);
          }
          pre -= len;
        } else if (inLength > 0) {
          if (pr.bool[PR_REVERSE]) { // ---- read reversed ----
            reInF.seekFrame(inOff - framesRead - len);
            reInF.readFrames(reInBuf, 0, len);
            for (ch = 0; ch < reInStream.channels; ch++) {
              convBuf1 = reInBuf[ch];
              for (i = 0, j = len - 1; i < j; i++, j--) {
                f1 = convBuf1[j];
                convBuf1[j] = convBuf1[i];
                convBuf1[i] = f1;
              }
            }
            if (pr.bool[PR_HASIMINPUT]) {
              imInF.seekFrame(inOff - framesRead - len);
              imInF.readFrames(imInBuf, 0, len);
              for (ch = 0; ch < imInStream.channels; ch++) {
                convBuf1 = imInBuf[ch];
                for (i = 0, j = len - 1; i < j; i++, j--) {
                  f1 = convBuf1[j];
                  convBuf1[j] = convBuf1[i];
                  convBuf1[i] = f1;
                }
              }
            } else if (complex) {
              Util.clear(imInBuf);
            }
          } else { // ---- read normal ----
            reInF.readFrames(reInBuf, 0, len);
            if (pr.bool[PR_HASIMINPUT]) {
              imInF.readFrames(imInBuf, 0, len);
            } else if (complex) {
              Util.clear(imInBuf);
            }
          }
          inLength -= len;
          framesRead += len;
        } else {
          Util.clear(reInBuf);
          if (complex) {
            Util.clear(imInBuf);
          }
          post -= len;
        }
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- save dry signal ----
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = reOutBuf[ch];
          for (i = 0; i < len; i++) {
            convBuf2[i] = convBuf1[i] * dryGain;
          }
          if (complex) {
            convBuf1 = imInBuf[ch];
            convBuf2 = imOutBuf[ch];
            for (i = 0; i < len; i++) {
              convBuf2[i] = convBuf1[i] * dryGain;
            }
          }
        }

        // ---- rectify + apply input gain ----
        for (ch = 0; ch < reInStream.channels; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = imInBuf[ch];
          // ---- rectify ----
          if (pr.bool[PR_RECTIFY]) {
            if (complex) {
              if (polarIn) {
                for (i = 0; i < len; i++) {
                  convBuf2[i] = 0.0f;
                }
              } else {
                for (i = 0; i < len; i++) {
                  d1 = convBuf1[i];
                  d2 = convBuf2[i];
                  convBuf1[i] = (float) Math.sqrt(d1 * d1 + d2 * d2);
                  convBuf2[i] = 0.0f;
                }
              }
            } else {
              for (i = 0; i < len; i++) {
                convBuf1[i] = Math.abs(convBuf1[i]);
              }
            }
          }
          // ---- apply input gain ----
          Util.mult(convBuf1, 0, len, inGain);
          if (complex & !polarIn) {
            Util.mult(convBuf2, 0, len, inGain);
          }
        }

        // ---- heart of the dragon ----
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = imInBuf[ch];

          switch (pr.intg[PR_OPERATOR]) {
            case OP_NONE: // ================ None ================
              for (i = 0; i < len; i++) {
                reOutBuf[ch][i] += wetGain * convBuf1[i];
              }
              if (complex) {
                for (i = 0; i < len; i++) {
                  imOutBuf[ch][i] += wetGain * convBuf2[i];
                }
              }
              break;

            case OP_SIN: // ================ Cosinus ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf1[i] * Math.PI);
                  imOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf2[i] * Math.PI);
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf1[i] * Math.PI);
                }
              }
              break;

            case OP_SQR: // ================ Square ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] +=
                      wetGain * (convBuf1[i] * convBuf1[i] - convBuf2[i] * convBuf2[i]);
                  imOutBuf[ch][i] -= wetGain * (convBuf1[i] * convBuf2[i] * 2);
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (convBuf1[i] * convBuf1[i]);
                }
              }
              break;

            case OP_SQRT: // ================ Square root ================
              if (complex) {
                d3 = phi[ch];
                k = wrap[ch];
                d4 = k * Constants.PI2;
                for (i = 0; i < len; i++) {
                  d1 =
                      wetGain
                          * Math.pow(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i], 0.25);
                  d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                  if (d2 - d3 > Math.PI) {
                    k--;
                    d4 = k * Constants.PI2;
                  } else if (d3 - d2 > Math.PI) {
                    k++;
                    d4 = k * Constants.PI2;
                  }
                  d2 += d4;
                  d3 = d2;
                  d2 /= 2;
                  reOutBuf[ch][i] += (float) (d1 * Math.cos(d2));
                  imOutBuf[ch][i] += (float) (d1 * Math.sin(d2));
                }
                phi[ch] = d3;
                wrap[ch] = k;

              } else {
                for (i = 0; i < len; i++) {
                  f1 = convBuf1[i];
                  if (f1 > 0) {
                    reOutBuf[ch][i] += wetGain * (float) Math.sqrt(f1);
                  } // else undefiniert
                }
              }
              break;

            case OP_RECT2POLARW: // ================ Rect->Polar (wrapped) ================
              for (i = 0; i < len; i++) {
                d1 = wetGain * Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                reOutBuf[ch][i] += (float) d1;
                imOutBuf[ch][i] += (float) d2;
              }
              break;

            case OP_RECT2POLAR: // ================ Rect->Polar ================
              d3 = phi[ch];
              k = wrap[ch];
              d4 = k * Constants.PI2;
              for (i = 0; i < len; i++) {
                d1 = wetGain * Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                if (d2 - d3 > Math.PI) {
                  k--;
                  d4 = k * Constants.PI2;
                } else if (d3 - d2 > Math.PI) {
                  k++;
                  d4 = k * Constants.PI2;
                }
                d2 += d4;
                reOutBuf[ch][i] += (float) d1;
                imOutBuf[ch][i] += (float) d2;
                d3 = d2;
              }
              phi[ch] = d3;
              wrap[ch] = k;
              break;

            case OP_POLAR2RECT: // ================ Polar->Rect ================
              for (i = 0; i < len; i++) {
                f1 = wetGain * convBuf1[i];
                reOutBuf[ch][i] += f1 * (float) Math.cos(convBuf2[i]);
                imOutBuf[ch][i] += f1 * (float) Math.sin(convBuf2[i]);
              }
              break;

            case OP_LOG: // ================ Log ================
              if (complex) {
                d3 = phi[ch];
                k = wrap[ch];
                d4 = k * Constants.PI2;
                d5 = carry[ch];
                for (i = 0; i < len; i++) {
                  d1 = Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                  d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                  if (d2 - d3 > Math.PI) {
                    k--;
                    d4 = k * Constants.PI2;
                  } else if (d3 - d2 > Math.PI) {
                    k++;
                    d4 = k * Constants.PI2;
                  }
                  if (d1 > 0.0) {
                    d5 = Math.log(d1);
                  }
                  d2 += d4;
                  reOutBuf[ch][i] += (float) d5;
                  imOutBuf[ch][i] += (float) d2;
                  d3 = d2;
                }
                phi[ch] = d3;
                wrap[ch] = k;
                carry[ch] = d5;

              } else {
                for (i = 0; i < len; i++) {
                  f1 = convBuf1[i];
                  if (f1 > 0) {
                    reOutBuf[ch][i] += wetGain * (float) Math.log(f1);
                  } // else undefiniert
                }
              }
              break;

            case OP_EXP: // ================ Exp ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  d1 = wetGain * Math.exp(convBuf1[i]);
                  reOutBuf[ch][i] += (float) (d1 * Math.cos(convBuf2[i]));
                  imOutBuf[ch][i] += (float) (d1 * Math.sin(convBuf2[i]));
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.exp(convBuf1[i]);
                }
              }
              break;

            case OP_NOT: // ================ NOT ================
              for (i = 0; i < len; i++) {
                lo = ~((long) (convBuf1[i] * 2147483647.0));
                reOutBuf[ch][i] += wetGain * (float) ((lo & 0xFFFFFFFFL) / 2147483647.0);
              }
              if (complex) {
                for (i = 0; i < len; i++) {
                  lo = ~((long) (convBuf2[i] * 2147483647.0));
                  imOutBuf[ch][i] += wetGain * (float) ((lo & 0xFFFFFFFFL) / 2147483647.0);
                }
              }
              break;
          }
        } // for outChan
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- write output chunk ----
        if (reFloatF != null) {
          for (ch = 0; ch < outChanNum; ch++) {
            reFloatF[ch].writeFloats(reOutBuf[ch], 0, len);
            if (pr.bool[PR_HASIMOUTPUT]) {
              imFloatF[ch].writeFloats(imOutBuf[ch], 0, len);
            }
          }
        } else {
          reOutF.writeFrames(reOutBuf, 0, len);
          if (pr.bool[PR_HASIMOUTPUT]) {
            imOutF.writeFrames(imOutBuf, 0, len);
          }
        }
        // check max amp
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reOutBuf[ch];
          for (i = 0; i < len; i++) {
            f1 = Math.abs(convBuf1[i]);
            if (f1 > maxAmp) {
              maxAmp = f1;
            }
          }
          if (pr.bool[PR_HASIMOUTPUT]) {
            convBuf1 = imOutBuf[ch];
            for (i = 0; i < len; i++) {
              f1 = Math.abs(convBuf1[i]);
              if (f1 > maxAmp) {
                maxAmp = f1;
              }
            }
          }
        }

        progOff += len;
        framesWritten += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
      } // while not framesWritten

      // ----==================== normalize output ====================----

      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        peakGain = new Param(maxAmp, Param.ABS_AMP);
        gain =
            (float)
                (Param.transform(
                        pr.para[PR_GAIN],
                        Param.ABS_AMP,
                        new Param(1.0 / peakGain.value, peakGain.unit),
                        null))
                    .value;
        f1 = pr.bool[PR_HASIMOUTPUT] ? ((1.0f + getProgression()) / 2) : 1.0f;
        normalizeAudioFile(reFloatF, reOutF, reOutBuf, gain, f1);
        if (pr.bool[PR_HASIMOUTPUT]) {
          normalizeAudioFile(imFloatF, imOutF, imOutBuf, gain, 1.0f);
        }
        maxAmp *= gain;

        for (ch = 0; ch < outChanNum; ch++) {
          reFloatF[ch].cleanUp();
          reFloatF[ch] = null;
          reTempFile[ch].delete();
          reTempFile[ch] = null;
          if (pr.bool[PR_HASIMOUTPUT]) {
            imFloatF[ch].cleanUp();
            imFloatF[ch] = null;
            imTempFile[ch].delete();
            imTempFile[ch] = null;
          }
        }
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Finish ----

      reOutF.close();
      reOutF = null;
      reOutStream = null;
      if (imOutF != null) {
        imOutF.close();
        imOutF = null;
        imOutStream = null;
      }
      reInF.close();
      reInF = null;
      reInStream = null;
      if (pr.bool[PR_HASIMINPUT]) {
        imInF.close();
        imInF = null;
        imInStream = null;
      }
      reOutBuf = null;
      imOutBuf = null;
      reInBuf = null;
      imInBuf = null;

      // inform about clipping/ low level
      handleClipping(maxAmp);
    } catch (IOException e1) {
      setError(e1);
    } catch (OutOfMemoryError e2) {
      reOutBuf = null;
      imOutBuf = null;
      reInBuf = null;
      imInBuf = null;
      convBuf1 = null;
      convBuf2 = null;
      System.gc();

      setError(new Exception(ERR_MEMORY));
    }

    // ---- cleanup (topLevel) ----
    convBuf1 = null;
    convBuf2 = null;

    if (reInF != null) {
      reInF.cleanUp();
      reInF = null;
    }
    if (imInF != null) {
      imInF.cleanUp();
      imInF = null;
    }
    if (reOutF != null) {
      reOutF.cleanUp();
      reOutF = null;
    }
    if (imOutF != null) {
      imOutF.cleanUp();
      imOutF = null;
    }
    if (reFloatF != null) {
      for (ch = 0; ch < reFloatF.length; ch++) {
        if (reFloatF[ch] != null) {
          reFloatF[ch].cleanUp();
          reFloatF[ch] = null;
        }
        if (reTempFile[ch] != null) {
          reTempFile[ch].delete();
          reTempFile[ch] = null;
        }
      }
    }
    if (imFloatF != null) {
      for (ch = 0; ch < imFloatF.length; ch++) {
        if (imFloatF[ch] != null) {
          imFloatF[ch].cleanUp();
          imFloatF[ch] = null;
        }
        if (imTempFile[ch] != null) {
          imTempFile[ch].delete();
          imTempFile[ch] = null;
        }
      }
    }
  } // process()
 protected void compute() {
   n = (int) ni[0].parseInput();
   t0 = ni[1].parseInput();
   deltat = ni[2].parseInput();
   x1 = ni[3].parseInput();
   x2 = ni[4].parseInput();
   sigma = ni[5].parseInput();
   // generate data points
   t = new DatanVector(n);
   y = new DatanVector(n);
   dy = new DatanVector(n);
   rand = DatanRandom.standardNormal(n);
   for (int i = 0; i < n; i++) {
     t.setElement(i, t0 + (double) i * deltat);
     y.setElement(i, x1 * Math.pow(t.getElement(i), x2) + sigma * rand[i]);
     dy.setElement(i, sigma);
   }
   // find 1st approximation of unknowns by method of log-log plot
   tlog = new double[n];
   ylog = new double[n];
   dellog = new double[n];
   int npos = 0;
   for (int i = 0; i < n; i++) {
     if (t.getElement(i) > 0. && y.getElement(i) > 0.) {
       tlog[npos] = Math.log(t.getElement(i));
       ylog[npos] = Math.log(y.getElement(i));
       dellog[npos] = 1.;
       npos++;
     }
   }
   DatanVector vtlog = new DatanVector(npos);
   DatanVector vylog = new DatanVector(npos);
   DatanVector vdellog = new DatanVector(npos);
   for (int j = 0; j < npos; j++) {
     vtlog.setElement(j, tlog[j]);
     vylog.setElement(j, ylog[j]);
     vdellog.setElement(j, dellog[j]);
   }
   LsqPol lp = new LsqPol(vtlog, vylog, vdellog, 2);
   x = lp.getResult();
   x.setElement(0, Math.exp(x.getElement(0)));
   df.writeLine(" x = " + x.toString());
   // perform fit
   int[] list = {1, 1};
   powerlaw = new Powerlaw();
   LsqNon ln = new LsqNon(t, y, dy, x, list, powerlaw);
   x = ln.getResult();
   x1 = x.getElement(0);
   x2 = x.getElement(1);
   cov = ln.getCovarianceMatrix();
   delx1 = Math.sqrt(cov.getElement(0, 0));
   delx2 = Math.sqrt(cov.getElement(1, 1));
   rho = cov.getElement(1, 0) / (delx1 * delx2);
   m = ln.getChiSquare();
   p = 1. - StatFunct.cumulativeChiSquared(m, n - 1);
   // curve of fitted exponential
   xpl = new double[1001];
   ypl = new double[1001];
   dpl = (double) (n - 1) * deltat / 1000.;
   for (int i = 0; i < 1001; i++) {
     xpl[i] = t0 + (double) i * dpl;
     ypl[i] = x1 * Math.pow(xpl[i], x2);
   }
   // prepare data points for plotting
   datx = new double[n];
   daty = new double[n];
   datsx = new double[n];
   datsy = new double[n];
   datrho = new double[n];
   for (int i = 0; i < n; i++) {
     datx[i] = t.getElement(i);
     daty[i] = y.getElement(i);
     datsx[i] = 0.;
     datsy[i] = dy.getElement(i);
     datrho[i] = 0.;
   }
   // display data and fitted curve
   caption =
       "x_1#="
           + String.format(Locale.US, "%5.2f", x1)
           + ", x_2#="
           + String.format(Locale.US, "%5.2f", x2)
           + ", &D@x_1#="
           + String.format(Locale.US, "%5.2f", delx1)
           + ", &D@x_2#="
           + String.format(Locale.US, "%5.2f", delx2)
           + ", &r@="
           + String.format(Locale.US, "%5.2f", rho)
           + ", M="
           + String.format(Locale.US, "%5.2f", m)
           + ", P="
           + String.format(Locale.US, "%6.4f", p);
   new GraphicsWithDataPointsAndPolyline(
       getClass().getName(),
       "",
       xpl,
       ypl,
       1,
       .3,
       datx,
       daty,
       datsx,
       datsy,
       datrho,
       "t",
       "y",
       caption);
 }
 public double evaluate(double x) {
   return Math.log(x * x + 1) - Math.exp(0.4 * x) * Math.cos(Math.PI * x);
 }
Beispiel #7
0
 // handy static methods
 public static double log10(double val) {
   return Math.log(val) * LOG10SCALE;
 }
Beispiel #8
0
/**
 * Includes a static function for selecting and labeling graph axis tic labels. given a numeric
 * range and a maximum number of tics, this class can produce a list of labels with the nicest round
 * numbers not exceeding a given maximum number of labels. the label generation code was extracted
 * from the public domain <a href="http://ptolemy.eecs.berkeley.edu/">Ptolomy project</a> at UC
 * Berkeley, taken from ptolemy/plot/PlotBox.java.
 *
 * <p>We added another static method to compute and draw an axis into a given AWT Graphics object. i
 * extracted the code for producing linear labels and threw out the vast majority of code that
 * attempted to produce log scale labels since that code was very broken. it was noted int the
 * Ptolomy code that the log label generation was itself based on a file named xgraph.c by David
 * Harrisonmy, and the comments say that the original code breaks down in certain cases. my drawAxis
 * method can still draw nicely labeling log scale axes because i simply use the linear scale label
 * generation code from Ptolomy and plot the tics in their proper locations on a log scale. the
 * resulting code produced exactly the same results as the Ptolemy code for log scales in those
 * ranges where the Ptolemy code did work, so this design is much better in all cases and uses only
 * a fraction of the original complexity. still, it can probably be further improved though the
 * exact problem is not well defined.
 *
 * @author M.Green and S.Chekanov
 */
public class Axis {
  private static final boolean DEBUG = false;
  public static final int X_AXIS = 0, Y_AXIS = 1;
  // For use in calculating log base 10. A log times this is a log base 10.
  private static final double LOG10SCALE = 1 / Math.log(10);

  // handy static methods
  public static double log10(double val) {
    return Math.log(val) * LOG10SCALE;
  }

  public static double exp10(double val) {
    return Math.exp(val / LOG10SCALE);
  }

  public static float flog10(double val) {
    return (float) log10(val);
  }

  public static float fexp10(double val) {
    return (float) exp10(val);
  }

  /**
   * Calculation of the separation length between tics. Some smart rounding algorithms are needed to
   * get the scaling properly in case of data going to 10.3 or so... Useful stuff stolen from the
   * Gnuplot sources, thank you guys!!
   */
  public static double calculateTicSep(double min, double max, int maxNumberOfTicks) {
    double xnorm, tic, posns;
    double lrange = log10(Math.abs(min - max));
    double fl = Math.floor(lrange);
    xnorm = Math.pow(10.0, lrange - fl);
    posns = maxNumberOfTicks / xnorm;

    if (posns > 40) tic = 0.05; // eg 0, .05, .10, ...
    else if (posns > 20) tic = 0.1; // eg 0, .1, .2, ...
    else if (posns > 10) tic = 0.2; // eg 0,0.2,0.4,...
    else if (posns > 4) tic = 0.5; // 0,0.5,1,
    else if (posns > 1) tic = 1; // 0,1,2,....
    else if (posns > 0.5) tic = 2; // 0, 2, 4, 6
    else if (posns > 0.2) tic = 10; // 0, 10, 100, 6
    else tic = Math.ceil(xnorm);

    tic *= Math.pow(10.0, fl);

    return tic;
  }

  /** Precompute number of ticks */
  public static int calculateTicNumber(
      double ticMinVal, double ticMaxVal, double xStep, boolean isLog) {

    int n = 0;

    // System.out.println("\n-- calculateTicNumber=");
    // System.out.println("Min="+Double.toString(ticMinVal));
    // System.out.println("Max="+Double.toString(ticMaxVal));
    // System.out.println("Max="+Double.toString(xStep));

    if (isLog == false) {
      double xStart = xStep * Math.ceil(ticMinVal / xStep);
      for (double xpos = xStart; xpos <= ticMaxVal; xpos += xStep) n++;
    } else {
      int t1 = 0;
      int t2 = 0;
      if (ticMinVal > 0) t1 = (int) Math.floor(log10(ticMinVal) - 0.5);
      if (ticMinVal < 0) t1 = -1 * (int) Math.floor(log10(-1 * ticMinVal) - 0.5);
      if (ticMaxVal > 0) t2 = (int) Math.floor(log10(ticMaxVal) + 1.0);
      if (ticMaxVal < 0) t2 = -1 * (int) Math.floor(log10(-1 * ticMaxVal) + 1.0);
      for (int i = t1; i < t2 + 1; i++) n++;
    }

    // System.out.println("Nr of ticks="+Integer.toString(n));

    return n;
  }

  /**
   * this is the central method of this class. takes axis range parameters and produces a list of
   * string representations of nicely rounded numbers within the given range. these strings are
   * intended for use as axis tic labels. note: to find out where to plot each tic label simply use
   * <br>
   * <code>float ticval = Float.parseFloat(ticstring);</code>
   *
   * @param ticMinVal no tics will be created for less than this value.
   * @param ticMaxVal no tics will be created for greater than this value.
   * @param maxTics returned vector will contain no more labels than this number.
   * @param isLog set to true in case of log10 numbers
   * @return a Vector containing formatted label strings which should also be parsable into floating
   *     point numbers (in order to plot them).
   */
  public static Vector<String> computeTicks(
      double ticMinVal, double ticMaxVal, int maxTicks, boolean isLog) {
    // double xStep = roundUp((ticMaxVal-ticMinVal)/maxTicks);

    double xStep = calculateTicSep(ticMinVal, ticMaxVal, maxTicks);

    int numfracdigits = numFracDigits(xStep);

    // Compute x starting point so it is a multiple of xStep.
    double xStart = xStep * Math.ceil(ticMinVal / xStep);
    Vector xgrid = null;
    Vector<String> labels = new Vector<String>();
    // Label the axis. The labels are quantized so that
    // they don't have excess resolution.

    if (!isLog) {
      for (double xpos = xStart; xpos <= ticMaxVal; xpos += xStep) {
        String snum = formatNum(xpos, numfracdigits);
        labels.addElement(snum);
      }
      // log scale: special case
    } else {

      int t1 = 0;
      int t2 = 0;
      if (ticMinVal > 0) t1 = (int) Math.floor(log10(ticMinVal) - 0.5);
      if (ticMinVal < 0) t1 = -1 * (int) Math.floor(log10(-1 * ticMinVal) - 0.5);
      if (ticMaxVal > 0) t2 = (int) Math.floor(log10(ticMaxVal) + 1.0);
      if (ticMaxVal < 0) t2 = -1 * (int) Math.floor(log10(-1 * ticMaxVal) + 1.0);

      // System.out.println("min = " + xmin + ", max = " + xmax);
      for (int i = t1; i < t2 + 1; i++) {
        double pp = Math.pow(10.0, i);
        // System.out.println(pp);
        labels.addElement(Double.toString(pp));
      }
    }

    return labels;
  }

  /**
   * high-level method for drawing a chart axis line plus labeled tic marks. introduces a dependancy
   * on AWT because it takes a Graphics parameter. perhaps this method belongs in some higher-level
   * class but i added it here since it's highly related with the tic lable generation code.
   *
   * @author Melinda Green
   * @param axis is one of Axis.X_AXIS or Axis.Y_AXIS.
   * @param maxTics is the maximum number of labeled tics to draw. note: the actual number drawn may
   *     be less.
   * @param lowVal is the smallest value tic mark that may be drawn. note: the lowest valued tic
   *     label may be greater than this limit.
   * @param highVal is the largest value tic mark that may be drawn. note: the highest valued tic
   *     label may be less than this limit.
   * @param screenStart is the coordinate in the low valued direction.
   * @param screenEnd is the coordinate in the high valued direction.
   * @param offset is the coordinate in the direction perpendicular to the specified direction.
   * @param logScale is true if a log scale axis is to be drawn, false for a linear scale.
   * @param screenHeight is needed to flip Y coordinates.
   * @param g is the AWT Graphics object to draw into. note: all drawing will be done in the current
   *     color of the given Graphics object.
   */
  public static void drawAxis(
      int axis,
      int maxTics,
      int ticLength,
      float lowVal,
      float highVal,
      int screenStart,
      int screenEnd,
      int screenOffset,
      boolean logScale,
      int screenHeight,
      Graphics g) {
    if (logScale && (lowVal == 0 || highVal == 0))
      throw new IllegalArgumentException("Axis.drawAxis: zero range value not allowed in log axes");
    if (axis == X_AXIS) // horizontal baseline
    g.drawLine(screenStart, screenHeight - screenOffset, screenEnd, screenHeight - screenOffset);
    else
      // vertical baseline
      g.drawLine(screenOffset, screenStart, screenOffset, screenEnd);
    Vector tics = Axis.computeTicks(lowVal, highVal, maxTics, logScale); // nice
    // round
    // numbers
    // for
    // tic
    // labels
    int last_label_end = axis == X_AXIS ? -88888 : 88888;
    String dbgstr = "tics:    ";
    for (Enumeration e = tics.elements(); e.hasMoreElements(); ) {
      String ticstr = (String) e.nextElement();
      if (DEBUG) dbgstr += ticstr + ", ";
      float ticval = Float.parseFloat(ticstr);
      int tic_coord = screenStart;
      Dimension str_size = stringSize(ticstr, g);
      tic_coord +=
          plotValue(ticval, lowVal, highVal, screenStart, screenEnd, logScale, screenHeight);
      if (axis == X_AXIS) { // horizontal axis == vertical tics
        g.drawLine(
            tic_coord,
            screenHeight - screenOffset,
            tic_coord,
            screenHeight - screenOffset + ticLength);
        if (tic_coord - str_size.width / 2 > last_label_end) {
          g.drawString(
              ticstr,
              tic_coord - str_size.width / 2,
              screenHeight - screenOffset + str_size.height + 5);
          last_label_end = tic_coord + str_size.width / 2 + str_size.height / 2;
        }
      } else { // vertical axis == horizontal tics
        tic_coord = screenHeight - tic_coord; // flips Y coordinates
        g.drawLine(screenOffset - ticLength, tic_coord, screenOffset, tic_coord);
        if (tic_coord - str_size.height / 3 < last_label_end) {
          g.drawString(
              ticstr,
              screenOffset - ticLength - str_size.width - 5,
              tic_coord + str_size.height / 3);
          last_label_end = tic_coord - str_size.height;
        }
      }
    }
    if (DEBUG) System.out.println(dbgstr);
  } // end drawAxis

  /**
   * lower level method to determine a screen location where a given value should be plotted given
   * range, type, and screen information. the "val" parameter is the data value to be plotted
   *
   * @author Melinda Green
   * @param val is a data value to be plotted.
   * @return pixel offset (row or column) to draw a screen representation of the given data value.
   *     i.e. <i>where</i> along an axis in screen coordinates the caller should draw a
   *     representation of the given value.
   * @see drawAxis(int,int,int,float,float,int,int,int,boolean,int,Graphics)
   */
  public static int plotValue(
      float val,
      float lowVal,
      float highVal,
      int screenStart,
      int screenEnd,
      boolean logScale,
      int screenHeight) {
    if (logScale && (lowVal == 0 || highVal == 0 || val == 0))
      throw new IllegalArgumentException("Axis.drawAxis: zero range value not allowed in log axes");
    int screen_range = screenEnd - screenStart; // in pixels
    if (logScale) {
      float log_low = flog10(lowVal), log_high = flog10(highVal), log_val = flog10(val);
      float log_range = log_high - log_low;
      float pixels_per_log_unit = screen_range / log_range;
      return (int) ((log_val - log_low) * pixels_per_log_unit + .5);
    } else {
      float value_range = highVal - lowVal; // in data value units
      float pixels_per_unit = screen_range / value_range;
      return (int) ((val - lowVal) * pixels_per_unit + .5);
    }
  }

  /*
   * Given a number, round up to the nearest power of ten times 1, 2, or 5.
   *
   * Note: The argument must be strictly positive.
   */
  private static double roundUp(double val) {
    int exponent = (int) Math.floor(log10(val));
    val *= Math.pow(10, -exponent);
    if (val > 5.0) val = 10.0;
    else if (val > 2.0) val = 5.0;
    else if (val > 1.0) val = 2.0;
    val *= Math.pow(10, exponent);
    return val;
  }

  /*
   * Return the number of fractional digits required to display the given
   * number. No number larger than 15 is returned (if more than 15 digits are
   * required, 15 is returned).
   */
  private static int numFracDigits(double num) {
    int numdigits = 0;
    while (numdigits <= 15 && num != Math.floor(num)) {
      num *= 10.0;
      numdigits += 1;
    }
    return numdigits;
  }

  // Number format cache used by formatNum.
  // Note: i'd have put the body of the formatNum method below into
  // a synchronized block for complete thread safety but that causes
  // an abscure null pointer exception in the awt event thread.
  // go figure.
  private static NumberFormat numberFormat = null;

  /*
   * Return a string for displaying the specified number using the specified
   * number of digits after the decimal point. NOTE: java.text.NumberFormat is
   * only present in JDK1.1 We use this method as a wrapper so that we can
   * cache information.
   */
  private static String formatNum(double num, int numfracdigits) {
    if (numberFormat == null) {
      // Cache the number format so that we don't have to get
      // info about local language etc. from the OS each time.
      // numberFormat = NumberFormat.getInstance();
      numberFormat = NumberFormat.getInstance(Locale.ENGLISH);
      // force to not include commas because we want the strings
      // to be parsable back into numeric values. - DRG
      numberFormat.setGroupingUsed(false);
    }
    numberFormat.setMinimumFractionDigits(numfracdigits);
    numberFormat.setMaximumFractionDigits(numfracdigits);
    return numberFormat.format(num);
  }

  /**
   * handy little utility for determining the length in pixels the given string will use if drawn
   * into the given Graphics object. Note: perhaps belongs in some utility package.
   */
  public static Dimension stringSize(String str, Graphics g) {
    if (g instanceof Graphics2D) {
      java.awt.geom.Rectangle2D bounds =
          g.getFont().getStringBounds(str, ((Graphics2D) g).getFontRenderContext());
      return new Dimension((int) (bounds.getWidth() + .5), (int) (bounds.getHeight() + .5));
    } else
      return new Dimension(g.getFontMetrics().stringWidth(str), g.getFontMetrics().getHeight());
  }

  //
  // TEST CODE FROM HERE DOWN
  //

  private static class TestPanel extends JPanel {
    private float curLowVal, curHighVal;
    private boolean logScale;

    public TestPanel(float initialLow, float initialHigh) {
      curLowVal = initialLow;
      curHighVal = initialHigh;
    }

    public void setLogScale(boolean logScale) {
      this.logScale = logScale;
      repaint();
    }

    public void setLow(float val) {
      curLowVal = val;
      repaint();
    }

    public void setHigh(float val) {
      curHighVal = val;
      repaint();
    }

    public void paint(Graphics g) {
      super.paint(g);
      drawAxis(
          Axis.X_AXIS,
          10,
          5,
          curLowVal,
          curHighVal,
          50,
          getWidth() - 50,
          50,
          logScale,
          getHeight(),
          g);
      drawAxis(
          Axis.Y_AXIS,
          10,
          5,
          curLowVal,
          curHighVal,
          50,
          getHeight() - 50,
          50,
          logScale,
          getHeight(),
          g);
      g.drawString("Current Slider Range: " + curLowVal + " --> " + curHighVal, 10, 20);
    }
  }

  private static void addField(
      Container into,
      Component c,
      GridBagConstraints gbc,
      int x,
      int y,
      int w,
      int h,
      int wx,
      int wy) {
    gbc.gridx = x;
    gbc.gridy = y;
    gbc.gridwidth = w;
    gbc.gridheight = h;
    gbc.weightx = wx;
    gbc.weighty = wy;
    into.add(c, gbc);
  }

  /** simple example program for Axis class. */
  public static void main(String args[]) {

    /*
     * final float INITIAL_MIN_LOW=1, INITIAL_MAX_HIGH=1000; final TestPanel
     * axis = new TestPanel(INITIAL_MIN_LOW, INITIAL_MAX_HIGH); final JFrame
     * frame = new JFrame("Axis Test"); JPanel mainpanel = new JPanel(new
     * BorderLayout()); mainpanel.add("Center", axis); JPanel controls = new
     * JPanel(); final JCheckBox logScale = new JCheckBox("Log");
     * logScale.addActionListener(new ActionListener() { public void
     * actionPerformed(ActionEvent ae) {
     * axis.setLogScale(logScale.isSelected()); } });
     * logScale.setSelected(true); axis.setLogScale(true);
     *
     * final JTextField minlow = new JTextField(""+INITIAL_MIN_LOW, 6);
     * final FloatSlider lowSlider = new FloatSlider(JSlider.HORIZONTAL,
     * INITIAL_MIN_LOW, 100, 1, 1000, 2000, false); final FloatSlider
     * highSlider = new FloatSlider(JSlider.HORIZONTAL, INITIAL_MAX_HIGH,
     * 100, 1, 1000, 2000, false); final JTextField maxhigh = new
     * JTextField(""+INITIAL_MAX_HIGH, 6); GridBagLayout gridbag = new
     * GridBagLayout(); controls.setLayout(gridbag); GridBagConstraints con
     * = new GridBagConstraints(); con.fill = GridBagConstraints.BOTH;
     * con.insets = new Insets(0, 10, 0, 0); addField(controls, logScale,
     * con, 0, 0, 1, 1, 5, 100); addField(controls, new
     * JLabel("min low value"), con, 1, 0, 1, 1, 10, 100);
     * addField(controls, minlow, con, 2, 0, 1, 1, 10, 100);
     * addField(controls, lowSlider, con, 3, 0, 1, 1, 50, 100);
     * addField(controls, highSlider, con, 4, 0, 1, 1, 50, 100);
     * addField(controls, new JLabel("max high value"), con, 5, 0, 1, 1, 10,
     * 100); addField(controls, maxhigh, con, 6, 0, 1, 1, 10, 100);
     * mainpanel.add("South", controls); KeyListener limitsWatcher = new
     * KeyAdapter() { public void keyTyped(KeyEvent ke) { if(ke.getKeyChar()
     * == KeyEvent.VK_ENTER) { float newminlow =
     * Float.parseFloat(minlow.getText()); float newmaxhigh =
     * Float.parseFloat(maxhigh.getText()); lowSlider.setAll(newminlow,
     * newmaxhigh, lowSlider.getFloatValue()); highSlider.setAll(newminlow,
     * newmaxhigh, highSlider.getFloatValue()); } } };
     * minlow.addKeyListener(limitsWatcher);
     * maxhigh.addKeyListener(limitsWatcher); AdjustmentListener
     * slider_watcher = new AdjustmentListener() { public void
     * adjustmentValueChanged(AdjustmentEvent ae) { if (ae.getSource() ==
     * lowSlider) axis.setLow((float)lowSlider.getFloatValue()); else
     * axis.setHigh((float)highSlider.getFloatValue()); } };
     * lowSlider.addAdjustmentListener(slider_watcher);
     * highSlider.addAdjustmentListener(slider_watcher);
     * frame.getContentPane().add(mainpanel); frame.setSize(new
     * Dimension(1000, 400));
     * frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     * frame.setVisible(true);
     */
  } // end main
}