實驗二 插值方法(android)
實驗一部落格地址:http://blog.csdn.net/double2hao/article/details/51152843
一、實驗內容
分別寫出拉格朗日插值法與牛頓插值法的演算法,編寫程式上機除錯出結果,要求所程式設計序適用於在任何一組插值節點,即能解決這一類問題,而不是某一個問題。
試驗中以下列資料驗證程式的正確性。
已知下列函式表
X 0.56160 0.56280 0.56401 0.56521
Y 0.82741 0.82659 0.82577 0.82495
求X=0.5635時的函式值。
最終效果:(原始碼在文章底部)
主要工作:
1、理解拉格朗日插值法和牛頓插值法的公式。
2、由於採用的是fragment,直接複用的實驗一的xml佈局。
3、牛頓插值法的演算法中採用了遞迴,為了提高效率直接在遞迴中判斷是否要加入牛頓插值的結果。
具體演算法就不多說了,主要邏輯寫在TwoFragment中,若對此作業有興趣可以自行拖到底部下載原始碼。
TwoFragment.java
package com.example.double2.numericcalculationtest;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.text.DecimalFormat;
/**
* 專案名稱:NumericCalculationTest
* 建立人:Double2號
* 建立時間:2016/4/13 21:41
* 修改備註:
*/
public class TwoFragment extends Fragment {
private View views;
private TextView tvTitle;
private TextView tvGuidance;
private Button btnInPut;
private EditText etInput;
private Button btnClear;
private TextView tvProgress;
private TextView tvResult;
private Spinner spChose;
private final String[] spinnerChose = {"Lagrange插值", "Newton插值"};
private String xShow;//用來展示過程
private String yShow;//用來展示過程
private int dataSize;
private Double[][] data;
private Double myX;
private int linePosition;//行座標
private Double resultNewton = 0.0;
private boolean[] hasAdded; //記錄該均差是否已經計算過,加入過了結構
private DecimalFormat mDecimalFormat = new DecimalFormat("0.00000000");//保留八位小數
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
views = inflater.inflate(R.layout.fra_one_and_two, null);
initView();
return views;
}
private void initView() {
tvTitle = (TextView) views.findViewById(R.id.tv_title);
tvGuidance = (TextView) views.findViewById(R.id.tv_one_guidance);
btnInPut = (Button) views.findViewById(R.id.btn_input);
etInput = (EditText) views.findViewById(R.id.et_input);
btnClear = (Button) views.findViewById(R.id.btn_clear);
tvProgress = (TextView) views.findViewById(R.id.tv_one_progress);
tvResult = (TextView) views.findViewById(R.id.tv_one_result);
spChose = (Spinner) views.findViewById(R.id.sp_one_chose);
tvTitle.setText("插值方法");
tvGuidance.setText(R.string.input_data_size);
spChose.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, spinnerChose));
btnInPut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
caculating();
}
});
btnClear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clearData();
}
});
}
private void clearData() {
tvGuidance.setText(R.string.input_data_size);
xShow = "";
yShow = "";
tvProgress.setText("");
tvResult.setText("");
linePosition = 0;
dataSize = 0;
data = null;
hasAdded = null;
btnInPut.setClickable(true);
}
private void caculating() {
//獲取到EditText中的String
//如果為空就提示使用者並且直接返回
String textInput = etInput.getText().toString();
etInput.setText("");
if (textInput.equals("")) {
Toast.makeText(getActivity(), R.string.not_input_null, Toast.LENGTH_SHORT).show();
return;
}
//Lagrange插值和Newton插值在計算之前的讀取資料過程一樣
readData(textInput);
}
private void readData(String textInput) {
String textGuidance = tvGuidance.getText().toString();
//通過提示的TextView的text來判斷進行到哪一步
if (textGuidance.equals(getString(R.string.input_data_size))) {
dataSize = Integer.parseInt(textInput);
data = new Double[2][dataSize];
xShow = "x分別為:\n";
yShow = "y分別為:\n";
tvProgress.setText(xShow + yShow);
tvGuidance.setText(R.string.input_x);
linePosition = 0;
} else if (textGuidance.equals(getString(R.string.input_x))) {
data[0][linePosition] = Double.parseDouble(textInput);
Log.d("xujiajia1", data[0][linePosition] + "");
xShow += data[0][linePosition] + "\n";
tvProgress.setText(xShow + yShow);
tvGuidance.setText(R.string.input_y);
} else if (textGuidance.equals(getString(R.string.input_y))) {
data[1][linePosition] = Double.parseDouble(textInput);
yShow += data[1][linePosition] + "\n";
tvProgress.setText(xShow + yShow);
linePosition++;
//倘若還沒有輸入完
if (linePosition != dataSize) {
tvGuidance.setText(R.string.input_x);
} else {
tvGuidance.setText(R.string.input_my_x);
yShow += "你需要測的x為:\n";
tvProgress.setText(xShow + yShow);
}
} else if (textGuidance.equals(getString(R.string.input_my_x))) {
myX = Double.parseDouble(textInput);
yShow += myX + "\n";
tvProgress.setText(xShow + yShow);
tvGuidance.setText(R.string.input_end);
if (spChose.getSelectedItemPosition() == 0) {
LagrangeCaculation();
} else {
NewtonCaculation();
}
}
}
private void LagrangeCaculation() {
Double result = 0.0;
Double aloneResule;
for (int i = 0; i < dataSize; i++) {
aloneResule = data[1][i];
for (int j = 0; j < dataSize; j++) {
if (i != j) {
aloneResule *= (myX - data[0][j]) / (data[0][i] - data[0][j]);
}
}
result += aloneResule;
}
tvResult.setText(mDecimalFormat.format(result) + "");
btnInPut.setClickable(false);
}
private void NewtonCaculation() {
hasAdded = new boolean[dataSize];
for (int i = 0; i < dataSize; i++) {
hasAdded[i] = false;
}
int[] dataIndex = new int[dataSize];
for (int i = 0; i < dataSize; i++)
dataIndex[i] = i;
resultNewton = data[1][0];//初始值為
hasAdded[0] = true;
meanDeviation(dataIndex);//開始遞迴
tvResult.setText(mDecimalFormat.format(resultNewton) + "");
btnInPut.setClickable(false);
}
//計算均差的遞迴,並且在每次遞迴的時候判斷是否要加入到結果裡
private Double meanDeviation(int[] dataIndex) {
int size = dataIndex.length;
Double deviation;
if (size == 1) {
deviation = data[1][0];
} else if (size == 2) {
deviation = (data[1][dataIndex[1]] - data[1][dataIndex[0]]) /
(data[0][dataIndex[1]] - data[0][dataIndex[0]]);
} else {
//如果大於二就進入遞迴
int[] dataIndex_one = new int[size - 1];
int[] dataIndex_two = new int[size - 1];
for (int i = 0; i < size - 2; i++) {
dataIndex_one[i] = dataIndex[i];
dataIndex_two[i] = dataIndex[i];
}
dataIndex_one[size - 2] = dataIndex[size - 1];
dataIndex_two[size - 2] = dataIndex[size - 2];
deviation = (meanDeviation(dataIndex_one) - meanDeviation(dataIndex_two)) /
(data[0][dataIndex[size - 1]] - data[0][dataIndex[size - 2]]);
}
//判斷這個值是否要加到newton插值的結果中
boolean isNeedAdd = true;
if (dataIndex[0] == 0) {
for (int i = 0; i < size - 1; i++) {
if (dataIndex[i] != dataIndex[i + 1] - 1) {
isNeedAdd = false;
break;
}
}
} else {
isNeedAdd = false;
}
//如果是滿足要求的均差並且沒有新增過,那麼久新增
if (isNeedAdd && !hasAdded[size - 1]) {
hasAdded[size - 1] = true;
double item = deviation;
for (int j = 0; j < size - 1; j++) {
Log.d("xujiajia4", size + " " + data[0][j]);
item *= (myX - data[0][j]);
Log.d("xujiajia4", item + "");
}
resultNewton += item;
}
return deviation;
}
}
原始碼地址:http://download.csdn.net/detail/double2hao/9498851
相關文章
- 二、插值操作
- 九種常見二維插值方法及雙線性插值的理解
- 【Android 動畫】動畫詳解之插值器(二)Android動畫
- MATLAB一維插值和二維插值 比較Matlab
- 介紹一種二維線性插值計算方法
- scala實現球面插值(Slerp)
- SCSS #{} 插值CSS
- Android實現二值點陣圖識別Android
- 【數值計算方法】常微分方程數值解-數值實驗
- arcgis js多執行緒克里金插值初體驗JS執行緒
- 【數值計算方法】非線性方程求根-數值實驗
- 《計算方法 》 - 第2章 插值法 - 解題套路
- 求插值係數
- 插值技術研究
- c#-string 插值C#
- 【java】【插值查詢】Java
- Android編譯期插樁,讓程式自己寫程式碼(二)Android編譯
- 數值分析Python實現系列—— 一、拉格朗日插值法Python
- Android影像灰度化、線性灰度變化、二值化處理方法Android
- 拉格朗日插值
- B樣條插值加速
- 【數值計算方法】線性方程組的迭代解法-數值實驗
- 實驗二
- Android屬性動畫基礎:你是否真的瞭解插值器(TimeInterpolator)Android動畫
- Android 位元組碼插樁Android
- 洛谷P4781 【模板】拉格朗日插值(拉格朗日插值)
- Swift 5 字串插值之美Swift字串
- 2.Vue插值表示式Vue
- 插值查詢演算法演算法
- Swift 5 字串插值-簡介Swift字串
- 演算法-查詢(線性、二分、插值、斐波那契)演算法
- vue.js插值與表示式Vue.js
- MemoryCache 的原生插值方式淺談
- 插值查詢的簡單理解
- Java實驗二:類程式設計實驗Java程式設計
- 實驗一和實驗二截圖
- 實驗二-需求分析
- 實驗二:需求分析
- 網路實驗二