掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.24840

Lias法->算術符号
投稿者---lias(2005/12/16 20:26:30)


以下のソースはLias法なのですが、
算術符号にするときに
wariaiというのを計算するのに無限小数が必要になり、
多倍長小数で計算するにしても、計算が不可になると思うのですが、
どうすればいいですか?
よろしくお願いします。
VisualC++ WindowsXP

#include<stdio.h>
#include<string.h>
#include <string>
void historyset(double *history,char *str,int strcnt,int *encountsum)
{
    (*encountsum)=0;
    memset(history,0,sizeof(double)*256);
    for(int i=0;i<strcnt;i++)
    {
        history[str[i]]++;
        (*encountsum)++;
    }
    return;
}
void wariaiset(double *wariai,double *history,int encountsum)
{
    for(int i=0;i<256;i++)
    {
        wariai[i]=history[i]/(double)encountsum;
    }
    return;
}
void probabilityset(double *probability,double *wariai,double small,double large)
{
    double sum=0;
    for(int i=0;i<256;i++)
    {
        sum+=(large-small)*wariai[i];
        probability[i]=sum+small;
    }
    return;
}
int linecntget(double *probability,double line)
{
    for(int i=0;i<256;i++)
    {
        if(i!=0 && probability[i-1]<=line && line<=probability[i])
        {
            return i;
        }
        else if(i==0 && 0<=line && line<=probability[i])
        {
            return i;
        }
    }
    return -1;
}
double encord(double *wariai,char *str,int strcnt)
{
    double line;
    double probability[256];
    double small=0;
    double large=1;
    for(int i=0;i<strcnt;i++)
    {
        probabilityset(probability,wariai,small,large);
        if(str[i]-1>=0){small=probability[str[i]-1];}
        else{small=0;}
        large=probability[str[i]];
    }
    line=(small+large)/2.0;
    return line;
}
void decord(std::string *decstr,double *wariai,double line,int strcnt)
{
    double probability[256];
    double small=0;
    double large=1;
    int linecnt;
    probabilityset(probability,wariai,small,large);
    for(int i=0;i<strcnt;i++)
    {      
        linecnt=linecntget(probability,line);
        if(linecnt-1>=0){small=probability[linecnt-1];}
        else{small=0;}
        large=probability[linecnt];
        decstr->push_back(linecnt);
        line=(line-small)/(large-small);
    }
    return;
}
int main()
{
    double history[256];
    double wariai[256]; 
    char *str="###$$$RTGFTTT";
    int encount=0;
    double line;
    std::string decstr;
    historyset(history,str,(int)strlen(str),&encount);
    wariaiset(wariai,history,encount);
    line=encord(wariai,str,(int)strlen(str));
    decord(&decstr,wariai,line,(int)strlen(str));
    printf(decstr.substr().c_str());
    getchar();
    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:Lias法->算術符号 24842 RAPT 2005/12/16 20:35:46


No.24842

Re:Lias法->算術符号
投稿者---RAPT(2005/12/16 20:35:46)


小数処理をきちんとやりたいなら、分子と分母で値を管理し、
必要に応じて約分しつつ、値を保持する必要があると思います。


この投稿にコメントする

削除パスワード

No.24844

Re:Lias法->算術符号
投稿者---lias(2005/12/16 21:50:22)


>小数処理をきちんとやりたいなら、分子と分母で値を管理し、
>必要に応じて約分しつつ、値を保持する必要があると思います。
回答ありがとうございます。
わかりました、それでやってみようと思います。
ちょっと時間がかかりそうですが。
ありがとうございます。


この投稿にコメントする

削除パスワード

No.24895

Re:Lias法->算術符号
投稿者---lias(2005/12/21 22:50:56)


データ圧縮ハンドブック読んでいます。
0.00000-0.111111
の表現方法を勉強中です。
ソースも載っているので、それでわかるかもしれません。
ありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧