using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace CsTest
{ //可以确定的是n个插值点的拉格朗日多项式的最大次数为n
public class Ploy //多项式
{
public double[] a;//系数,指数即索引值
public Ploy(int n = 1)
{
a = new double[n]; //当未给数组中的每一项赋值时,其值为0
}
public static Ploy operator +(Ploy a1, Ploy b1)//多项式a1和b1的项数相同
{
Ploy p = new Ploy(a1.a.Length);
for (int i = 0; i < a1.a.Length; i++)
{
p.a[i] = a1.a[i] + b1.a[i];//系数相加
}
return p;
}
public static Ploy operator *(Ploy a1, Ploy b1)
{
Ploy p = new Ploy(a1.a.Length);
for (int i = 0; i < a1.a.Length; i++)
{
if (a1.a[i] == 0)
{
continue; //此项系数为0
}
for (int j = 0; j < a1.a.Length; j++)
{
if (b1.a[j] == 0)//此项系数为0
{
continue;
}
if (i + j > a1.a.Length)
{
Console.WriteLine("运算出现错误");
break;
}
p.a[i + j] += a1.a[i] * b1.a[j];
}
}
return p;
}
}
class Program
{
static void Lagrange(int[] X,int[]Y,out Ploy lag)
{
int n = 0;
n = X.Length;
lag = new Ploy(n);//拉格朗日多项式
for (int i = 0; i < n; i++)
{
Ploy py = new Ploy(X.Length);
py.a[0] = Y[i];
Ploy px = new Ploy(X.Length);
px.a[0] = 1;
for (int k = 0; k < X.Length; k++)
{
if (i != k)
{
px.a[0] *= X[i] - X[k];
}
}
py.a[0] /= px.a[0];
Ploy mul = new Ploy(n);
mul.a[0] = 1;
for (int j = 0; j < n; j++)
{
Ploy temp = new Ploy(n);
temp.a[1] = 1;
Ploy temp2 = new Ploy(n);
if (i == j)
{
continue;
}
temp2.a[0] = -X[j];
mul *= temp + temp2;
}
lag += py * mul;
}
}
static void Main(string[] args)
{
int n =4;//没选取n个节点进行一次拉格朗日运算
string Inpath = @"E://360壁纸//color.txt";//原数据文件路径
string Outpath = @"F://Rout.txt";//输出数据文件
StreamReader sr = new StreamReader(Inpath, Encoding.Default);
StreamWriter sw = new StreamWriter(Outpath, true);
string temps;
// ArrayList aL = new ArrayList();//将节点存入数组
while ((temps = sr.ReadLine()) != null)
{
int Length=0;
string[] s = temps.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);//根据空格区分数据
Length = s.Length; //获取一行有多少节点
int tempInt;
for (int i = 0; i < Length; i++)
{
tempInt = Convert.ToInt32(s[i]); //string转换成int,基本数据类型的转换
// aL.Add(tempInt);
}
int[] Z = new int[Length * 2 - 1];//存放当前行所做拉格朗日分段运算的值
for (int i = 0; i < Length-n+1; i++)//对当前行进行分段拉格朗日运算
{
int[] X = new int[n];
for (int j = 0; j < n; j++)
{
X[j] = j;
}
int[] Y = new int[n];
for (int k = 0; k < n; k++)
{
Y[k] = Convert.ToInt32(s[i + k]);
}
Ploy lag;
Program.Lagrange(X, Y, out lag);
int[] r = new int[n * 2 -1];
for (int m = 0; m < n; m++)//带入横坐标求值
{
double xhalf=Convert.ToDouble(m)+0.5;
double result=0;
for(int t=n-1;t>=0;t--)//求对应于result的拉格朗日值
{
result+=lag.a[t]*Math.Pow(xhalf,t);
}
r[m * 2] = Y[m];
if (result > 255)
result = 255;
if (m != n - 1)
{
r[m * 2 + 1] = Convert.ToInt32(result);
}
}
if (i == 0) //说明是第一个指定n个节点所做的拉格朗日运算
{
for (int m = 0; m < r.Length; m++)
{
Z[i + m] = r[m];
}
}
else //倒数第2个之前的值与Z中对应的值求平均
{
for (int m = 0; m < r.Length - 2; m++)
{
Z[i * 2+m] = (Z[i * 2+m] + r[m]) / 2;
}
Z[i*2+r.Length - 2] = r[r.Length - 2];
Z[i*2+r.Length - 1] = r[r.Length - 1];
}
}
//将Z中的值输出到文件中
for (int i = 0; i < Z.Length; i++)
{
sw.Write(Z[i].ToString()+" ");
}
sw.WriteLine();
}
sw.Flush();
sw.Close();
sr.Close();
//获取文件中的x值得数量并赋给n
//int[] X = new int[n]; //横坐标数组
//int[] Y = new int[n]; //纵坐标数组
//int[] X = { 0, 1, 2, 3 };
//int[] Y = { 2, -1, 4, 3 };
//输出拉格朗日多项式
/* for (int i = n - 1; i >= 0; i--)
{
if (lag.a[i] == 0)
continue;
Console.Write("{0}x^{1}+", lag.a[i], i);
}*/
}
}
}
拉格朗日插值对图片单色素大规模处理
本文转载:CSDN博客